<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>nocklock</title>
    <link>https://nocklock.tistory.com/</link>
    <description>개발하고, 읽고, 기술을 의심합니다.
자바 개발자가 다시 성장하며 직접 만든 것과 배운 것을 기록합니다.</description>
    <language>ko</language>
    <pubDate>Mon, 28 Sep 2026 01:45:10 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>nocklock</managingEditor>
    <image>
      <title>nocklock</title>
      <url>https://tistory1.daumcdn.net/tistory/9022158/attach/6baced2a2d2346acb25f248a44ec318a</url>
      <link>https://nocklock.tistory.com</link>
    </image>
    <item>
      <title>Docker localhost 연결 안 될 때 &amp;mdash; 8081:8080 포트 매핑부터 확인했다</title>
      <link>https://nocklock.tistory.com/36</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 22일 오후 06_11_45.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/692Fi/dJMb99Vs6Pg/chpFkyGeSkhvfYNsUepIB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/692Fi/dJMb99Vs6Pg/chpFkyGeSkhvfYNsUepIB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/692Fi/dJMb99Vs6Pg/chpFkyGeSkhvfYNsUepIB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F692Fi%2FdJMb99Vs6Pg%2FchpFkyGeSkhvfYNsUepIB1%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; alt=&quot;localhost error&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;ChatGPT Image 2026년 9월 22일 오후 06_11_45.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;584&quot; data-start=&quot;571&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot 프로젝트를 Docker로 실행했는데 localhost로 접속할 때 포트가 헷갈렸다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;http://localhost:8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;631&quot; data-start=&quot;621&quot; data-ke-size=&quot;size16&quot;&gt;을 입력하면 됐다.&lt;/p&gt;
&lt;p data-end=&quot;671&quot; data-start=&quot;633&quot; data-ke-size=&quot;size16&quot;&gt;그런데 Docker를 사용하기 시작하니 갑자기 이런 형태가 등장했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;docker run -p 8081:8080 my-spring-app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;763&quot; data-start=&quot;724&quot; data-ke-size=&quot;size16&quot;&gt;처음 봤을 때는 솔직히 숫자가 왜 두 개 필요한지 바로 와닿지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;786&quot; data-start=&quot;765&quot; data-ke-size=&quot;size16&quot;&gt;8081도 포트고 8080도 포트인데,&lt;/p&gt;
&lt;p data-end=&quot;814&quot; data-start=&quot;788&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;도대체 어느 쪽으로 접속해야 하는 걸까?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;870&quot; data-start=&quot;816&quot; data-ke-size=&quot;size16&quot;&gt;직접 Docker로 Spring Boot를 실행해보고 나서야 이 구조가 조금씩 이해되기 시작했다.&lt;/p&gt;
&lt;h2 data-end=&quot;895&quot; data-start=&quot;872&quot; data-section-id=&quot;1iazvcs&quot; data-ke-size=&quot;size26&quot;&gt;먼저 localhost부터 다시 봤다&lt;/h2&gt;
&lt;p data-end=&quot;933&quot; data-start=&quot;897&quot; data-ke-size=&quot;size16&quot;&gt;localhost는 인터넷에 있는 특정 서버의 이름이 아니다.&lt;/p&gt;
&lt;p data-end=&quot;968&quot; data-start=&quot;935&quot; data-ke-size=&quot;size16&quot;&gt;지금 프로그램이 실행되고 있는 &lt;b&gt;자기 자신&lt;/b&gt;을 가리킨다.&lt;/p&gt;
&lt;p data-end=&quot;985&quot; data-start=&quot;970&quot; data-ke-size=&quot;size16&quot;&gt;내 PC에서 브라우저를 열고&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;http://localhost:8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1050&quot; data-start=&quot;1022&quot; data-ke-size=&quot;size16&quot;&gt;으로 들어간다면 내 PC의 8080 포트를 찾는다.&lt;/p&gt;
&lt;p data-end=&quot;1099&quot; data-start=&quot;1052&quot; data-ke-size=&quot;size16&quot;&gt;그런데 Docker 컨테이너 안에서 localhost라고 하면 이야기가 달라진다.&lt;/p&gt;
&lt;p data-end=&quot;1163&quot; data-start=&quot;1101&quot; data-ke-size=&quot;size16&quot;&gt;Docker 컨테이너 입장에서 localhost는 &lt;b&gt;내 Windows PC가 아니라 그 컨테이너 자신&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;1195&quot; data-start=&quot;1165&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 처음 사용할 때 이 부분이 꽤 헷갈렸다.&lt;/p&gt;
&lt;p data-end=&quot;1250&quot; data-start=&quot;1197&quot; data-ke-size=&quot;size16&quot;&gt;같은 localhost라는 글자인데 실행되는 위치에 따라 가리키는 대상이 달라지기 때문이다.&lt;/p&gt;
&lt;h2 data-end=&quot;1281&quot; data-start=&quot;1252&quot; data-section-id=&quot;1gjrr38&quot; data-ke-size=&quot;size26&quot;&gt;내가 먼저 만난 문제는 8080 포트 충돌이었다&lt;/h2&gt;
&lt;p data-end=&quot;1316&quot; data-start=&quot;1283&quot; data-ke-size=&quot;size16&quot;&gt;당시 Spring Boot를 실행하려는데 이런 오류가 났다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;vhdl&quot;&gt;&lt;code&gt;Port 8080 was already in use&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-end=&quot;514&quot; data-start=&quot;447&quot; data-ke-size=&quot;size16&quot;&gt;당시 로컬 개발 중에는 8080 포트가 이미 사용 중이라 Spring Boot를 8081로 바꿔 실행한 적도 있었다.&lt;/p&gt;
&lt;p data-end=&quot;514&quot; data-start=&quot;447&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;629&quot; data-start=&quot;528&quot; data-ke-size=&quot;size16&quot;&gt;그런데 Docker에서는 조금 다르게 처리할 수 있었다. 컨테이너 내부의 Spring Boot는 기본 포트인 8080으로 실행하고, 내 PC에서 접근하는 포트만 8081로 매핑했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;docker run -p 8081:8080 my-spring-app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;718&quot; data-start=&quot;710&quot; data-ke-size=&quot;size16&quot;&gt;즉 이 경우에는&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;내 PC 8081 &amp;rarr; Docker Container 8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;800&quot; data-start=&quot;795&quot; data-ke-size=&quot;size16&quot;&gt;이 된다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;server.port=8081&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1501&quot; data-start=&quot;1473&quot; data-ke-size=&quot;size16&quot;&gt;그러면 로컬에서 접속하는 주소도 자연스럽게 바뀐다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;http://localhost:8081&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1552&quot; data-start=&quot;1538&quot; data-ke-size=&quot;size16&quot;&gt;여기까지는 어렵지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;1576&quot; data-start=&quot;1554&quot; data-ke-size=&quot;size16&quot;&gt;문제는 Docker를 사용하면서부터였다.&lt;/p&gt;
&lt;h2 data-end=&quot;1608&quot; data-start=&quot;1578&quot; data-section-id=&quot;w34o11&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Docker의 8081:8080은 무슨 뜻일까&lt;/span&gt;&lt;/h2&gt;
&lt;p data-end=&quot;1645&quot; data-start=&quot;1610&quot; data-ke-size=&quot;size16&quot;&gt;Docker 컨테이너를 실행할 때 이런 명령을 사용할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;docker run -p 8081:8080 my-spring-app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1702&quot; data-start=&quot;1698&quot; data-ke-size=&quot;size16&quot;&gt;처음에는&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;8081:8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1744&quot; data-start=&quot;1727&quot; data-ke-size=&quot;size16&quot;&gt;이 숫자 두 개가 꽤 헷갈렸다.&lt;/p&gt;
&lt;p data-end=&quot;1775&quot; data-start=&quot;1746&quot; data-ke-size=&quot;size16&quot;&gt;결론부터 말하면 나는 이렇게 이해하니까 가장 쉬웠다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;basic&quot;&gt;&lt;code&gt;8081 &amp;rarr; 내 PC에서 사용할 포트
8080 &amp;rarr; Docker 컨테이너 내부 포트&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1838&quot; data-start=&quot;1836&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;내 PC의 8081
        &amp;darr;
Docker 컨테이너의 8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1905&quot; data-start=&quot;1892&quot; data-ke-size=&quot;size16&quot;&gt;으로 연결해주는 것이다.&lt;/p&gt;
&lt;p data-end=&quot;1918&quot; data-start=&quot;1907&quot; data-ke-size=&quot;size16&quot;&gt;그래서 브라우저에서는&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;http://localhost:8081&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1962&quot; data-start=&quot;1955&quot; data-ke-size=&quot;size16&quot;&gt;로 접속한다.&lt;/p&gt;
&lt;p data-end=&quot;2024&quot; data-start=&quot;1964&quot; data-ke-size=&quot;size16&quot;&gt;하지만 Docker 컨테이너 내부의 Spring Boot 애플리케이션은 여전히 8080에서 실행될 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2102&quot; data-start=&quot;2026&quot; data-ke-size=&quot;size16&quot;&gt;기존 Docker 배포를 하면서 내가 사용했던 구조도 이 방식이었다. &lt;span data-content-reference-end=&quot;2092&quot; data-content-reference-start=&quot;2070&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;2135&quot; data-start=&quot;2104&quot; data-section-id=&quot;19fc96w&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;-p 앞뒤 순서를 반대로 생각하면 계속 헷갈린다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-end=&quot;2159&quot; data-start=&quot;2137&quot; data-ke-size=&quot;size16&quot;&gt;Docker의 포트 옵션은 다음 형태다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;diff&quot;&gt;&lt;code&gt;-p 호스트포트:컨테이너포트&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2195&quot; data-start=&quot;2190&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;docker run -p 8081:8080 my-spring-app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2251&quot; data-start=&quot;2248&quot; data-ke-size=&quot;size16&quot;&gt;이라면&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;Host        Container
8081   &amp;rarr;    8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2308&quot; data-start=&quot;2305&quot; data-ke-size=&quot;size16&quot;&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;2338&quot; data-start=&quot;2310&quot; data-ke-size=&quot;size16&quot;&gt;내가 외부에서 접속하는 포트는 &lt;b&gt;8081&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;2343&quot; data-start=&quot;2340&quot; data-ke-size=&quot;size16&quot;&gt;그래서&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;localhost:8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2378&quot; data-start=&quot;2373&quot; data-ke-size=&quot;size16&quot;&gt;이 아니라&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;localhost:8081&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2415&quot; data-start=&quot;2408&quot; data-ke-size=&quot;size16&quot;&gt;로 접속한다.&lt;/p&gt;
&lt;p data-end=&quot;2420&quot; data-start=&quot;2417&quot; data-ke-size=&quot;size16&quot;&gt;반대로&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;docker run -p 9000:8080 my-spring-app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2487&quot; data-start=&quot;2473&quot; data-ke-size=&quot;size16&quot;&gt;이라고 하면 브라우저에서는&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;http://localhost:9000&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2535&quot; data-start=&quot;2524&quot; data-ke-size=&quot;size16&quot;&gt;으로 들어가면 된다.&lt;/p&gt;
&lt;p data-end=&quot;2568&quot; data-start=&quot;2537&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너 내부 애플리케이션은 그대로 8080을 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;2611&quot; data-start=&quot;2570&quot; data-ke-size=&quot;size16&quot;&gt;이걸 한 번 이해하고 나니까 Docker 포트 설정이 훨씬 덜 무서워졌다.&lt;/p&gt;
&lt;h2 data-end=&quot;2655&quot; data-start=&quot;2613&quot; data-section-id=&quot;w7x5dp&quot; data-ke-size=&quot;size26&quot;&gt;EXPOSE 8080을 적었다고 8080이 자동으로 열리는 건 아니었다&lt;/h2&gt;
&lt;p data-end=&quot;2681&quot; data-start=&quot;2657&quot; data-ke-size=&quot;size16&quot;&gt;Dockerfile에는 이런 설정도 있었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;EXPOSE 8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2761&quot; data-start=&quot;2714&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 이것만 적으면 내 컴퓨터에서도 8080으로 바로 접속할 수 있는 줄 알았다.&lt;/p&gt;
&lt;p data-end=&quot;2806&quot; data-start=&quot;2763&quot; data-ke-size=&quot;size16&quot;&gt;그런데 EXPOSE는 실제 포트를 외부에 자동으로 열어주는 명령이라기보다,&lt;/p&gt;
&lt;blockquote data-end=&quot;2836&quot; data-start=&quot;2808&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2836&quot; data-start=&quot;2810&quot; data-ke-size=&quot;size16&quot;&gt;이 컨테이너의 애플리케이션이 이 포트를 사용한다&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2856&quot; data-start=&quot;2838&quot; data-ke-size=&quot;size16&quot;&gt;는 정보를 표현하는 것에 가깝다.&lt;/p&gt;
&lt;p data-end=&quot;2884&quot; data-start=&quot;2858&quot; data-ke-size=&quot;size16&quot;&gt;실제로 호스트와 컨테이너를 연결하려면 실행할 때&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;docker run -p 8081:8080 my-spring-app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2954&quot; data-start=&quot;2937&quot; data-ke-size=&quot;size16&quot;&gt;처럼 포트 매핑을 해줘야 한다.&lt;/p&gt;
&lt;p data-end=&quot;3031&quot; data-start=&quot;2956&quot; data-ke-size=&quot;size16&quot;&gt;이 차이도 Docker를 직접 실행해보기 전에는 잘 와닿지 않았다. &lt;span data-content-reference-end=&quot;3006&quot; data-content-reference-start=&quot;2984&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;3071&quot; data-start=&quot;3033&quot; data-section-id=&quot;1597nfg&quot; data-ke-size=&quot;size26&quot;&gt;그러면 Docker에서 localhost는 왜 자주 문제가 될까&lt;/h2&gt;
&lt;p data-end=&quot;3111&quot; data-start=&quot;3073&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 사용하기 전에는 대부분 내 PC 하나만 생각하면 된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;브라우저
Spring Boot
DB
기타 프로그램&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3172&quot; data-start=&quot;3154&quot; data-ke-size=&quot;size16&quot;&gt;이 모두 내 컴퓨터에서 돌아간다.&lt;/p&gt;
&lt;p data-end=&quot;3213&quot; data-start=&quot;3174&quot; data-ke-size=&quot;size16&quot;&gt;그래서 localhost라는 주소를 써도 크게 신경 쓸 일이 없다.&lt;/p&gt;
&lt;p data-end=&quot;3241&quot; data-start=&quot;3215&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 사용하면 경계가 하나 더 생긴다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;내 PC
│
├─ 브라우저
│
└─ Docker Container
      └─ Spring Boot&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3323&quot; data-start=&quot;3314&quot; data-ke-size=&quot;size16&quot;&gt;여기서 중요한 건&lt;/p&gt;
&lt;p data-end=&quot;3371&quot; data-start=&quot;3325&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내 PC와 Docker 컨테이너는 같은 localhost가 아니라는 것&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;3381&quot; data-start=&quot;3373&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너 안에서&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;localhost&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3432&quot; data-start=&quot;3406&quot; data-ke-size=&quot;size16&quot;&gt;를 호출하면 기본적으로 컨테이너 자신을 찾는다.&lt;/p&gt;
&lt;p data-end=&quot;3472&quot; data-start=&quot;3434&quot; data-ke-size=&quot;size16&quot;&gt;따라서 Docker 안의 애플리케이션이 다른 서비스에 접속해야 한다면&lt;/p&gt;
&lt;blockquote data-end=&quot;3508&quot; data-start=&quot;3474&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;3508&quot; data-start=&quot;3476&quot; data-ke-size=&quot;size16&quot;&gt;그 localhost가 누구 기준의 localhost인가?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;3521&quot; data-start=&quot;3510&quot; data-ke-size=&quot;size16&quot;&gt;부터 확인해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;3557&quot; data-start=&quot;3523&quot; data-ke-size=&quot;size16&quot;&gt;이 질문 하나만 해도 연결 문제를 볼 때 범위가 꽤 줄어든다.&lt;/p&gt;
&lt;h2 data-end=&quot;3588&quot; data-start=&quot;3559&quot; data-section-id=&quot;1dymixc&quot; data-ke-size=&quot;size26&quot;&gt;로컬에서는 됐는데 Railway에서는 또 달랐다&lt;/h2&gt;
&lt;p data-end=&quot;3628&quot; data-start=&quot;3590&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 로컬에서 실행한 뒤 실제 배포는 Railway로 했다.&lt;/p&gt;
&lt;p data-end=&quot;3650&quot; data-start=&quot;3630&quot; data-ke-size=&quot;size16&quot;&gt;여기서 또 하나 달라진 게 포트였다.&lt;/p&gt;
&lt;p data-end=&quot;3663&quot; data-start=&quot;3652&quot; data-ke-size=&quot;size16&quot;&gt;로컬에서는 내가 직접&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;8080
8081&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3709&quot; data-start=&quot;3688&quot; data-ke-size=&quot;size16&quot;&gt;같은 포트를 정해서 사용할 수 있었다.&lt;/p&gt;
&lt;p data-end=&quot;3757&quot; data-start=&quot;3711&quot; data-ke-size=&quot;size16&quot;&gt;하지만 클라우드 환경에서는 플랫폼이 사용할 포트를 환경변수로 전달하는 경우가 있다.&lt;/p&gt;
&lt;p data-end=&quot;3787&quot; data-start=&quot;3759&quot; data-ke-size=&quot;size16&quot;&gt;그래서 Spring Boot에서는 이렇게 설정했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;server.port=${PORT:8080}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3838&quot; data-start=&quot;3833&quot; data-ke-size=&quot;size16&quot;&gt;이 설정은&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;PORT 환경변수가 있다
&amp;rarr; 그 값 사용

PORT 환경변수가 없다
&amp;rarr; 8080 사용&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3909&quot; data-start=&quot;3901&quot; data-ke-size=&quot;size16&quot;&gt;이라는 의미다.&lt;/p&gt;
&lt;p data-end=&quot;4012&quot; data-start=&quot;3911&quot; data-ke-size=&quot;size16&quot;&gt;덕분에 로컬과 배포 환경을 따로 하드코딩하지 않아도 됐다. 내가 Railway 배포 때 사용한 방식도 이것이었다. &lt;span data-content-reference-end=&quot;3972&quot; data-content-reference-start=&quot;3950&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;4054&quot; data-start=&quot;4014&quot; data-section-id=&quot;1kxqy0f&quot; data-ke-size=&quot;size26&quot;&gt;localhost에서 외부 URL로 바뀌니까 그제야 배포가 실감났다&lt;/h2&gt;
&lt;p data-end=&quot;4086&quot; data-start=&quot;4056&quot; data-ke-size=&quot;size16&quot;&gt;Docker와 Railway 배포가 끝난 뒤에는 드디어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;localhost&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4131&quot; data-start=&quot;4111&quot; data-ke-size=&quot;size16&quot;&gt;가 아닌 실제 외부 URL이 생겼다.&lt;/p&gt;
&lt;p data-end=&quot;4157&quot; data-start=&quot;4133&quot; data-ke-size=&quot;size16&quot;&gt;PC에서도 접속해보고 휴대폰에서도 열어봤다.&lt;/p&gt;
&lt;p data-end=&quot;4204&quot; data-start=&quot;4159&quot; data-ke-size=&quot;size16&quot;&gt;그리고 내 컴퓨터에서 Spring Boot를 실행하지 않았는데도 서비스가 열렸다.&lt;/p&gt;
&lt;p data-end=&quot;4242&quot; data-start=&quot;4206&quot; data-ke-size=&quot;size16&quot;&gt;이때가 Docker를 공부하면서 가장 이해가 잘 됐던 순간이었다.&lt;/p&gt;
&lt;p data-end=&quot;4285&quot; data-start=&quot;4244&quot; data-ke-size=&quot;size16&quot;&gt;이미지, 컨테이너, 레이어 같은 용어를 먼저 공부할 때는 꽤 추상적이었다.&lt;/p&gt;
&lt;p data-end=&quot;4293&quot; data-start=&quot;4287&quot; data-ke-size=&quot;size16&quot;&gt;그런데 직접&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;내 PC에서 실행
&amp;darr;
Docker로 실행
&amp;darr;
외부 서버에서 실행
&amp;darr;
외부 URL로 접속&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4430&quot; data-start=&quot;4357&quot; data-ke-size=&quot;size16&quot;&gt;을 해보니까 Docker가 왜 필요한지 조금씩 보이기 시작했다. &lt;span data-content-reference-end=&quot;4375&quot; data-content-reference-start=&quot;4353&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;4477&quot; data-start=&quot;4432&quot; data-section-id=&quot;a5vc96&quot; data-ke-size=&quot;size26&quot;&gt;Docker localhost 연결이 안 된다면 나는 이 순서로 볼 것 같다&lt;/h2&gt;
&lt;p data-end=&quot;4509&quot; data-start=&quot;4479&quot; data-ke-size=&quot;size16&quot;&gt;다시 같은 문제가 생긴다면 우선 이걸 확인할 것 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;1. Spring Boot가 실제로 어느 포트에서 실행되고 있는가?

2. docker run의 -p 설정은 어떻게 되어 있는가?

3. 호스트 포트와 컨테이너 포트를 반대로 생각하고 있지는 않은가?

4. 접속할 때 컨테이너 포트가 아니라
   호스트 포트로 접속하고 있는가?

5. localhost가 현재 누구 기준의 localhost인가?

6. 클라우드라면 PORT 환경변수가 따로 주어지는가?&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4789&quot; data-start=&quot;4750&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 처음 사용할 때는 모든 게 Docker 문제처럼 보였다.&lt;/p&gt;
&lt;p data-end=&quot;4811&quot; data-start=&quot;4791&quot; data-ke-size=&quot;size16&quot;&gt;그런데 직접 하나씩 뜯어보니 대부분은&lt;/p&gt;
&lt;p data-end=&quot;4844&quot; data-start=&quot;4813&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;어디에서 실행되고 있고, 어느 포트를 보고 있는가&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4853&quot; data-start=&quot;4846&quot; data-ke-size=&quot;size16&quot;&gt;의 문제였다.&lt;/p&gt;
&lt;p data-end=&quot;4860&quot; data-start=&quot;4855&quot; data-ke-size=&quot;size16&quot;&gt;나는 특히&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;8081:8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4911&quot; data-start=&quot;4885&quot; data-ke-size=&quot;size16&quot;&gt;을 직접 사용해보면서 이 개념이 확실히 잡혔다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;내 PC 8081 &amp;rarr; Docker 8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4999&quot; data-start=&quot;4950&quot; data-ke-size=&quot;size16&quot;&gt;이 한 줄을 이해하고 나니 localhost와 Docker 포트가 훨씬 덜 헷갈렸다.&lt;/p&gt;
&lt;hr data-end=&quot;5004&quot; data-start=&quot;5001&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;5020&quot; data-start=&quot;5006&quot; data-section-id=&quot;er48m&quot; data-ke-size=&quot;size26&quot;&gt;같이 읽으면 좋은 글&lt;/h2&gt;
&lt;h3 data-end=&quot;5065&quot; data-start=&quot;5022&quot; data-section-id=&quot;383zz1&quot; data-ke-size=&quot;size23&quot;&gt;Spring Boot를 Docker로 실제 배포하면서 막혔던 전체 과정&lt;/h3&gt;
&lt;p data-end=&quot;5136&quot; data-start=&quot;5067&quot; data-ke-size=&quot;size16&quot;&gt;Windows와 WSL에서 시작해서 Docker 이미지를 만들고 Railway에 올리기까지의 과정은 이 글에 따로 정리했다.&lt;/p&gt;
&lt;p data-end=&quot;5239&quot; data-start=&quot;5138&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://nocklock.tistory.com/24&quot; data-end=&quot;5239&quot; data-start=&quot;5141&quot;&gt;- Spring Boot Docker 배포 방법 &amp;mdash; Windows/WSL부터 Railway까지 직접 해보며 막힌 것들&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-end=&quot;5278&quot; data-start=&quot;5241&quot; data-section-id=&quot;13l0yyf&quot; data-ke-size=&quot;size23&quot;&gt;localhost를 벗어나 실제 서비스로 만들면서 느꼈던 것&lt;/h3&gt;
&lt;p data-end=&quot;5327&quot; data-start=&quot;5280&quot; data-ke-size=&quot;size16&quot;&gt;같은 경험을 해결 방법이 아니라 개발 과정과 생각 중심으로 적은 RE:개발자 글이다.&lt;/p&gt;
&lt;p data-end=&quot;5411&quot; data-start=&quot;5329&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://nocklock.tistory.com/19&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;-localhost를 지웠더니 진짜 서비스가 됐다 | RE:개발자 #12&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>개발 노트</category>
      <category>8080포트</category>
      <category>8081포트</category>
      <category>docker</category>
      <category>Dockerlocalhost</category>
      <category>Docker포트매핑</category>
      <category>localhost</category>
      <category>railway</category>
      <category>springboot</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/36</guid>
      <comments>https://nocklock.tistory.com/36#entry36comment</comments>
      <pubDate>Sun, 27 Sep 2026 20:30:00 +0900</pubDate>
    </item>
    <item>
      <title>사진 위치정보(EXIF&amp;middot;GPS) 확인&amp;middot;삭제 방법 &amp;mdash; 내가 찍은 사진엔 어디까지 남을까?</title>
      <link>https://nocklock.tistory.com/35</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 22일 오후 05_53_50.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciyqbc/dJMcacR58Jw/Wdh7SYXsA6E4KvJkJA21S0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciyqbc/dJMcacR58Jw/Wdh7SYXsA6E4KvJkJA21S0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciyqbc/dJMcacR58Jw/Wdh7SYXsA6E4KvJkJA21S0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fciyqbc%2FdJMcacR58Jw%2FWdh7SYXsA6E4KvJkJA21S0%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; alt=&quot;사진에 정보가 남아있다&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 22일 오후 05_53_50.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;293&quot; data-start=&quot;258&quot; data-ke-size=&quot;size16&quot;&gt;사진을 업로드하면 그냥 이미지 파일 하나가 올라가는 줄 알았다.&lt;/p&gt;
&lt;p data-end=&quot;359&quot; data-start=&quot;295&quot; data-ke-size=&quot;size16&quot;&gt;그런데 Security Lens를 만들면서 이미지의 메타데이터를 직접 읽어보니까 생각보다 많은 정보가 붙어 있었다.&lt;/p&gt;
&lt;p data-end=&quot;385&quot; data-start=&quot;361&quot; data-ke-size=&quot;size16&quot;&gt;GPS 위치 정보, 촬영 시간, 기기 정보.&lt;/p&gt;
&lt;p data-end=&quot;450&quot; data-start=&quot;387&quot; data-ke-size=&quot;size16&quot;&gt;이미지에 보이는 내용만 확인하면 될 거라고 생각했는데, 정작 사진 뒤쪽에는 눈에 보이지 않는 정보가 따로 있었다.&lt;/p&gt;
&lt;p data-end=&quot;462&quot; data-start=&quot;452&quot; data-ke-size=&quot;size16&quot;&gt;그래서 궁금해졌다.&lt;/p&gt;
&lt;p data-end=&quot;500&quot; data-start=&quot;464&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 평소 찍는 사진에도 이런 정보가 그대로 남아 있을까?&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;529&quot; data-start=&quot;502&quot; data-section-id=&quot;f8fcfk&quot; data-ke-size=&quot;size26&quot;&gt;사진에는 이미지 말고 다른 정보도 들어 있다&lt;/h2&gt;
&lt;p data-end=&quot;568&quot; data-start=&quot;531&quot; data-ke-size=&quot;size16&quot;&gt;사진 파일에는 사진 자체뿐 아니라 여러 부가정보가 저장될 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;647&quot; data-start=&quot;570&quot; data-ke-size=&quot;size16&quot;&gt;이런 정보를 보통 &lt;b&gt;메타데이터(metadata)&lt;/b&gt;라고 부르고, 카메라나 스마트폰 사진에서는 &lt;b&gt;EXIF&lt;/b&gt;라는 말을 자주 보게 된다.&lt;/p&gt;
&lt;p data-end=&quot;682&quot; data-start=&quot;649&quot; data-ke-size=&quot;size16&quot;&gt;EXIF에는 촬영 환경에 따라 이런 정보가 들어갈 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;752&quot; data-start=&quot;684&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;695&quot; data-start=&quot;684&quot; data-section-id=&quot;itq0ch&quot;&gt;촬영 날짜와 시간&lt;/li&gt;
&lt;li data-end=&quot;712&quot; data-start=&quot;696&quot; data-section-id=&quot;l2pbk1&quot;&gt;카메라 또는 스마트폰 기종&lt;/li&gt;
&lt;li data-end=&quot;721&quot; data-start=&quot;713&quot; data-section-id=&quot;17snlp4&quot;&gt;이미지 크기&lt;/li&gt;
&lt;li data-end=&quot;729&quot; data-start=&quot;722&quot; data-section-id=&quot;1jdjn3o&quot;&gt;노출 시간&lt;/li&gt;
&lt;li data-end=&quot;735&quot; data-start=&quot;730&quot; data-section-id=&quot;1o4925&quot;&gt;ISO&lt;/li&gt;
&lt;li data-end=&quot;743&quot; data-start=&quot;736&quot; data-section-id=&quot;1mihcka&quot;&gt;조리개 값&lt;/li&gt;
&lt;li data-end=&quot;752&quot; data-start=&quot;744&quot; data-section-id=&quot;1x7xfq4&quot;&gt;GPS 좌표&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;785&quot; data-start=&quot;754&quot; data-ke-size=&quot;size16&quot;&gt;물론 모든 사진에 이 정보가 전부 들어가는 것은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;837&quot; data-start=&quot;787&quot; data-ke-size=&quot;size16&quot;&gt;특히 GPS 정보는 카메라 앱의 위치 권한이나 기기 설정에 따라 저장되지 않을 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;948&quot; data-start=&quot;839&quot; data-ke-size=&quot;size16&quot;&gt;아이폰의 경우 카메라 앱에 위치 서비스 권한이 있으면 사진이나 영상에 위치 좌표가 포함될 수 있다고 Apple도 안내하고 있다. &lt;span data-content-reference-end=&quot;952&quot; data-content-reference-start=&quot;928&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;975&quot; data-start=&quot;950&quot; data-section-id=&quot;zcbtwa&quot; data-ke-size=&quot;size26&quot;&gt;직접 EXIF를 읽어보니 GPS가 보였다&lt;/h2&gt;
&lt;p data-end=&quot;1023&quot; data-start=&quot;977&quot; data-ke-size=&quot;size16&quot;&gt;Security Lens를 개발하면서 이미지 업로드 기능에 EXIF 분석을 붙였다.&lt;/p&gt;
&lt;p data-end=&quot;1054&quot; data-start=&quot;1025&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 OCR로 사진 속 글자만 분석할 생각이었다.&lt;/p&gt;
&lt;p data-end=&quot;1095&quot; data-start=&quot;1056&quot; data-ke-size=&quot;size16&quot;&gt;그런데 개인정보 관점에서 생각해보니 사진 안의 글자만 문제가 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;1125&quot; data-start=&quot;1097&quot; data-ke-size=&quot;size16&quot;&gt;사진 파일 자체에 들어 있는 정보도 확인해야 했다.&lt;/p&gt;
&lt;p data-end=&quot;1164&quot; data-start=&quot;1127&quot; data-ke-size=&quot;size16&quot;&gt;그래서 EXIF 데이터를 읽도록 만들었고 테스트 이미지에서는 실제로&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;GPS 정보
촬영 시간
기기 정보&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1209&quot; data-start=&quot;1198&quot; data-ke-size=&quot;size16&quot;&gt;같은 값이 감지됐다.&lt;/p&gt;
&lt;p data-end=&quot;1236&quot; data-start=&quot;1211&quot; data-ke-size=&quot;size16&quot;&gt;사진만 봤을 때는 전혀 알 수 없는 정보였다.&lt;/p&gt;
&lt;p data-end=&quot;1262&quot; data-start=&quot;1238&quot; data-ke-size=&quot;size16&quot;&gt;여기서 조금 소름 돋았던 부분은 GPS였다.&lt;/p&gt;
&lt;p data-end=&quot;1354&quot; data-start=&quot;1264&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 집에서 찍은 사진이나 자주 가는 장소에서 찍은 사진에 GPS 좌표가 남아 있고, 그 원본 파일을 그대로 전달한다면 촬영 위치를 알아낼 가능성이 생긴다.&lt;/p&gt;
&lt;p data-end=&quot;1377&quot; data-start=&quot;1356&quot; data-ke-size=&quot;size16&quot;&gt;그래서 사진을 인터넷에 올릴 때 단순히&lt;/p&gt;
&lt;p data-end=&quot;1402&quot; data-start=&quot;1379&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;사진 속에 개인정보가 찍혔는가?&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1414&quot; data-start=&quot;1404&quot; data-ke-size=&quot;size16&quot;&gt;만 볼 게 아니라,&lt;/p&gt;
&lt;p data-end=&quot;1446&quot; data-start=&quot;1416&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;사진 파일 자체에도 개인정보가 남아 있는가?&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1467&quot; data-start=&quot;1448&quot; data-ke-size=&quot;size16&quot;&gt;도 한 번쯤 확인할 필요가 있었다.&lt;/p&gt;
&lt;h2 data-end=&quot;1503&quot; data-start=&quot;1469&quot; data-section-id=&quot;1fznyzw&quot; data-ke-size=&quot;size26&quot;&gt;Windows에서 사진 EXIF 확인하는 가장 쉬운 방법&lt;/h2&gt;
&lt;p data-end=&quot;1540&quot; data-start=&quot;1505&quot; data-ke-size=&quot;size16&quot;&gt;별도 프로그램을 설치하지 않아도 간단한 정보는 확인할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1567&quot; data-start=&quot;1542&quot; data-ke-size=&quot;size16&quot;&gt;Windows 기준으로는 사진 파일을 선택하고&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;사진 우클릭
&amp;rarr; 속성
&amp;rarr; 자세히&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1610&quot; data-start=&quot;1600&quot; data-ke-size=&quot;size16&quot;&gt;로 들어가면 된다.&lt;/p&gt;
&lt;p data-end=&quot;1623&quot; data-start=&quot;1612&quot; data-ke-size=&quot;size16&quot;&gt;여기에서 사진에 따라&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1677&quot; data-start=&quot;1625&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1632&quot; data-start=&quot;1625&quot; data-section-id=&quot;qbya61&quot;&gt;촬영 날짜&lt;/li&gt;
&lt;li data-end=&quot;1642&quot; data-start=&quot;1633&quot; data-section-id=&quot;17v46fo&quot;&gt;카메라 제조사&lt;/li&gt;
&lt;li data-end=&quot;1651&quot; data-start=&quot;1643&quot; data-section-id=&quot;c39z44&quot;&gt;카메라 모델&lt;/li&gt;
&lt;li data-end=&quot;1657&quot; data-start=&quot;1652&quot; data-section-id=&quot;1o4925&quot;&gt;ISO&lt;/li&gt;
&lt;li data-end=&quot;1665&quot; data-start=&quot;1658&quot; data-section-id=&quot;1jdjn3o&quot;&gt;노출 시간&lt;/li&gt;
&lt;li data-end=&quot;1677&quot; data-start=&quot;1666&quot; data-section-id=&quot;oeobb9&quot;&gt;GPS 관련 정보&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1691&quot; data-start=&quot;1679&quot; data-ke-size=&quot;size16&quot;&gt;등이 표시될 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1733&quot; data-start=&quot;1693&quot; data-ke-size=&quot;size16&quot;&gt;사진마다 저장된 정보가 다르기 때문에 아무것도 나오지 않는 항목도 있다.&lt;/p&gt;
&lt;p data-end=&quot;1821&quot; data-start=&quot;1735&quot; data-ke-size=&quot;size16&quot;&gt;개발하면서 EXIF 라이브러리로 읽는 것보다 이 방법이 훨씬 간단해서, 그냥 사진에 뭐가 들어 있는지 궁금한 사람이라면 우선 이 방법부터 확인해보면 된다.&lt;/p&gt;
&lt;h2 data-end=&quot;1847&quot; data-start=&quot;1823&quot; data-section-id=&quot;1pcwsh&quot; data-ke-size=&quot;size26&quot;&gt;아이폰에서 사진 위치정보 확인하는 방법&lt;/h2&gt;
&lt;p data-end=&quot;1872&quot; data-start=&quot;1849&quot; data-ke-size=&quot;size16&quot;&gt;아이폰에서는 사진 앱에서 확인할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1926&quot; data-start=&quot;1874&quot; data-ke-size=&quot;size16&quot;&gt;사진을 열고 정보 화면을 보면 촬영 위치가 저장된 사진은 지도나 위치 정보가 표시될 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1947&quot; data-start=&quot;1928&quot; data-ke-size=&quot;size16&quot;&gt;위치 정보를 지우고 싶다면 사진에서&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;더보기
&amp;rarr; 위치 조정
&amp;rarr; 위치 없음&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1993&quot; data-start=&quot;1982&quot; data-ke-size=&quot;size16&quot;&gt;을 선택할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2024&quot; data-start=&quot;1995&quot; data-ke-size=&quot;size16&quot;&gt;아예 앞으로 카메라가 위치정보를 저장하지 않게 하려면&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;설정
&amp;rarr; 개인정보 보호 및 보안
&amp;rarr; 위치 서비스
&amp;rarr; 카메라&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2090&quot; data-start=&quot;2072&quot; data-ke-size=&quot;size16&quot;&gt;에서 위치 권한을 끌 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;2198&quot; data-start=&quot;2092&quot; data-ke-size=&quot;size16&quot;&gt;Apple은 사진을 공유할 때만 위치정보를 제외하는 방법도 제공한다. 공유 화면에서 옵션을 누른 뒤 위치를 끄면 된다. &lt;span data-content-reference-end=&quot;2189&quot; data-content-reference-start=&quot;2165&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2223&quot; data-start=&quot;2200&quot; data-ke-size=&quot;size16&quot;&gt;개인적으로는 이 방법이 꽤 괜찮아 보였다.&lt;/p&gt;
&lt;p data-end=&quot;2310&quot; data-start=&quot;2225&quot; data-ke-size=&quot;size16&quot;&gt;평소에는 사진 앱에서 장소별 검색을 사용하면서 위치정보를 유지하고, 외부로 원본 사진을 공유할 때만 위치정보를 제외하는 식으로 사용할 수 있기 때문이다.&lt;/p&gt;
&lt;h2 data-end=&quot;2338&quot; data-start=&quot;2312&quot; data-section-id=&quot;h7h83w&quot; data-ke-size=&quot;size26&quot;&gt;안드로이드 사진도 위치정보가 남을 수 있다&lt;/h2&gt;
&lt;p data-end=&quot;2353&quot; data-start=&quot;2340&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드도 마찬가지다.&lt;/p&gt;
&lt;p data-end=&quot;2400&quot; data-start=&quot;2355&quot; data-ke-size=&quot;size16&quot;&gt;카메라 앱에서 위치 저장 기능이 켜져 있으면 촬영 위치가 사진에 포함될 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2556&quot; data-start=&quot;2402&quot; data-ke-size=&quot;size16&quot;&gt;Google Photos에서는 사진의 위치를 확인할 수 있고, 카메라에서 위치정보 저장 자체를 끄려면 기기의 &lt;b&gt;카메라 설정에서 위치 저장 기능을 비활성화&lt;/b&gt;하면 된다. 제조사마다 메뉴 이름은 조금씩 다르다. &lt;span data-content-reference-end=&quot;2534&quot; data-content-reference-start=&quot;2510&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2575&quot; data-start=&quot;2558&quot; data-ke-size=&quot;size16&quot;&gt;여기서 하나 주의할 점이 있다.&lt;/p&gt;
&lt;p data-end=&quot;2613&quot; data-start=&quot;2577&quot; data-ke-size=&quot;size16&quot;&gt;Google Photos에서 표시되는 위치는 두 종류일 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2695&quot; data-start=&quot;2615&quot; data-ke-size=&quot;size16&quot;&gt;하나는 카메라가 실제 사진 파일에 저장한 위치이고, 다른 하나는 Google Photos가 주변 사진이나 랜드마크 등을 이용해서 추정한 위치다.&lt;/p&gt;
&lt;p data-end=&quot;2873&quot; data-start=&quot;2697&quot; data-ke-size=&quot;size16&quot;&gt;Google 공식 안내를 보면 Google Photos에서 직접 수정하거나 삭제할 수 있는 것은 주로 &lt;b&gt;추정된 위치나 사용자가 추가한 위치&lt;/b&gt;이고, 카메라가 사진에 기록한 위치는 Google Photos 안에서 바로 제거할 수 없는 경우가 있다. &lt;span data-content-reference-end=&quot;2856&quot; data-content-reference-start=&quot;2814&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2895&quot; data-start=&quot;2875&quot; data-ke-size=&quot;size16&quot;&gt;이 차이는 처음 보면 조금 헷갈린다.&lt;/p&gt;
&lt;h2 data-end=&quot;2925&quot; data-start=&quot;2897&quot; data-section-id=&quot;a3ec9i&quot; data-ke-size=&quot;size26&quot;&gt;사진 위치정보를 아예 남기지 않는 게 좋을까?&lt;/h2&gt;
&lt;p data-end=&quot;2954&quot; data-start=&quot;2927&quot; data-ke-size=&quot;size16&quot;&gt;여기까지 확인하고 나면 이런 생각이 들 수 있다.&lt;/p&gt;
&lt;blockquote data-end=&quot;2990&quot; data-start=&quot;2956&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2990&quot; data-start=&quot;2958&quot; data-ke-size=&quot;size16&quot;&gt;그러면 GPS 저장은 무조건 꺼두는 게 안전한 거 아닌가?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;3013&quot; data-start=&quot;2992&quot; data-ke-size=&quot;size16&quot;&gt;그런데 꼭 그렇다고 생각하지는 않는다.&lt;/p&gt;
&lt;p data-end=&quot;3031&quot; data-start=&quot;3015&quot; data-ke-size=&quot;size16&quot;&gt;위치정보가 있으면 사진 앱에서&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3075&quot; data-start=&quot;3033&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3045&quot; data-start=&quot;3033&quot; data-section-id=&quot;yqod4o&quot;&gt;여행지별 사진 정리&lt;/li&gt;
&lt;li data-end=&quot;3064&quot; data-start=&quot;3046&quot; data-section-id=&quot;moekjx&quot;&gt;특정 장소에서 찍은 사진 검색&lt;/li&gt;
&lt;li data-end=&quot;3075&quot; data-start=&quot;3065&quot; data-section-id=&quot;tky7m5&quot;&gt;여행 기록 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3097&quot; data-start=&quot;3077&quot; data-ke-size=&quot;size16&quot;&gt;같은 기능을 편하게 사용할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;3120&quot; data-start=&quot;3099&quot; data-ke-size=&quot;size16&quot;&gt;결국 위치정보 자체가 나쁜 건 아니다.&lt;/p&gt;
&lt;p data-end=&quot;3170&quot; data-start=&quot;3122&quot; data-ke-size=&quot;size16&quot;&gt;문제는 &lt;b&gt;내가 위치정보가 들어 있다는 사실을 모르고 원본 사진을 공유하는 경우&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-end=&quot;3194&quot; data-start=&quot;3172&quot; data-ke-size=&quot;size16&quot;&gt;그래서 나는 지금은 이렇게 보는 편이다.&lt;/p&gt;
&lt;p data-end=&quot;3241&quot; data-start=&quot;3196&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;위치정보를 무조건 없애기보다는, 외부로 공유할 사진은 한 번 확인하는 것.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3269&quot; data-start=&quot;3243&quot; data-ke-size=&quot;size16&quot;&gt;이 정도만 해도 꽤 많은 문제를 줄일 수 있다.&lt;/p&gt;
&lt;h2 data-end=&quot;3299&quot; data-start=&quot;3271&quot; data-section-id=&quot;rx7kal&quot; data-ke-size=&quot;size26&quot;&gt;특히 원본 사진을 전달할 때 한 번 확인해보자&lt;/h2&gt;
&lt;p data-end=&quot;3348&quot; data-start=&quot;3301&quot; data-ke-size=&quot;size16&quot;&gt;메신저나 SNS는 업로드 과정에서 메타데이터를 일부 제거하거나 변환하는 경우가 있다.&lt;/p&gt;
&lt;p data-end=&quot;3410&quot; data-start=&quot;3350&quot; data-ke-size=&quot;size16&quot;&gt;하지만 서비스마다 처리 방식이 다르고, 파일 첨부나 원본 전송처럼 원본이 그대로 전달되는 경우도 있기 때문에&lt;/p&gt;
&lt;p data-end=&quot;3450&quot; data-start=&quot;3412&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;어차피 플랫폼이 지워주겠지&amp;rdquo;라고 생각하는 건 조금 위험하다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3480&quot; data-start=&quot;3452&quot; data-ke-size=&quot;size16&quot;&gt;특히 아래 같은 사진이라면 한 번 확인해볼 만하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3562&quot; data-start=&quot;3482&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3493&quot; data-start=&quot;3482&quot; data-section-id=&quot;1ii7rrk&quot;&gt;집에서 찍은 사진&lt;/li&gt;
&lt;li data-end=&quot;3501&quot; data-start=&quot;3494&quot; data-section-id=&quot;1x8m2fk&quot;&gt;아이 사진&lt;/li&gt;
&lt;li data-end=&quot;3512&quot; data-start=&quot;3502&quot; data-section-id=&quot;kxzs9g&quot;&gt;회사 내부 사진&lt;/li&gt;
&lt;li data-end=&quot;3523&quot; data-start=&quot;3513&quot; data-section-id=&quot;sg80wg&quot;&gt;중고거래용 사진&lt;/li&gt;
&lt;li data-end=&quot;3544&quot; data-start=&quot;3524&quot; data-section-id=&quot;1dkvotw&quot;&gt;온라인 커뮤니티에 올릴 원본 사진&lt;/li&gt;
&lt;li data-end=&quot;3562&quot; data-start=&quot;3545&quot; data-section-id=&quot;1w48rfg&quot;&gt;모르는 사람에게 전달할 사진&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3618&quot; data-start=&quot;3564&quot; data-ke-size=&quot;size16&quot;&gt;사진 속 배경을 가렸는데 정작 파일 안에 GPS가 남아 있다면 조금 허무한 상황이 될 수도 있다.&lt;/p&gt;
&lt;h2 data-end=&quot;3648&quot; data-start=&quot;3620&quot; data-section-id=&quot;1m84s8p&quot; data-ke-size=&quot;size26&quot;&gt;사진 한 장은 생각보다 많은 것을 알고 있었다&lt;/h2&gt;
&lt;p data-end=&quot;3694&quot; data-start=&quot;3650&quot; data-ke-size=&quot;size16&quot;&gt;예전에 &lt;b&gt;&amp;lsquo;사진 한 장은 생각보다 많은 것을 알고 있다&amp;rsquo;&lt;/b&gt;라는 글을 썼다.&lt;/p&gt;
&lt;p data-end=&quot;3728&quot; data-start=&quot;3696&quot; data-ke-size=&quot;size16&quot;&gt;그때는 사진 안에 포함될 수 있는 정보 자체가 흥미로웠다.&lt;/p&gt;
&lt;p data-end=&quot;3770&quot; data-start=&quot;3730&quot; data-ke-size=&quot;size16&quot;&gt;그런데 직접 개발하면서 EXIF 데이터를 읽어보니 조금 다르게 느껴졌다.&lt;/p&gt;
&lt;p data-end=&quot;3811&quot; data-start=&quot;3772&quot; data-ke-size=&quot;size16&quot;&gt;사진에 들어 있는 개인정보는 꼭 눈에 보이는 글자나 얼굴만은 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;3828&quot; data-start=&quot;3813&quot; data-ke-size=&quot;size16&quot;&gt;파일 안에도 정보가 있었다.&lt;/p&gt;
&lt;p data-end=&quot;3870&quot; data-start=&quot;3830&quot; data-ke-size=&quot;size16&quot;&gt;사진을 인터넷에 올릴 때마다 모든 EXIF를 검사할 필요까지는 없겠지만,&lt;/p&gt;
&lt;p data-end=&quot;3944&quot; data-start=&quot;3872&quot; data-ke-size=&quot;size16&quot;&gt;적어도 &lt;b&gt;원본 사진을 낯선 곳에 전달하기 전에는 위치정보가 남아 있는지 한 번 확인하는 습관&lt;/b&gt; 정도는 있어도 괜찮을 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;4003&quot; data-start=&quot;3946&quot; data-ke-size=&quot;size16&quot;&gt;그리고 이 경험 때문에 Security Lens에서도 OCR뿐 아니라 EXIF까지 같이 확인하게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;4063&quot; data-start=&quot;4005&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 이미지 속 글자만 보려고 했는데, 만들다 보니 결국 사진이라는 파일 자체를 조금 더 보게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;4097&quot; data-start=&quot;4070&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4097&quot; data-start=&quot;4070&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4114&quot; data-start=&quot;4099&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;같이 읽으면 좋은 글&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4114&quot; data-start=&quot;4099&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span data-content-reference-end=&quot;322&quot; data-content-reference-start=&quot;260&quot;&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;a href=&quot;https://nocklock.tistory.com/9?utm_source=chatgpt.com&quot;&gt;- 사진 한 장은 생각보다 많은 것을 알고 있다.&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;4114&quot; data-start=&quot;4099&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span data-content-reference-end=&quot;504&quot; data-content-reference-start=&quot;424&quot;&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;a href=&quot;https://nocklock.tistory.com/8?utm_source=chatgpt.com&quot;&gt;- OCR로 개인정보를 찾기 시작했다, 하드코딩을 걷어낸 날 | RE:개발자 #6&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>기술이 조금 무섭다</category>
      <category>exif</category>
      <category>GPS</category>
      <category>개인정보</category>
      <category>사진메타데이터</category>
      <category>사진위치정보</category>
      <category>위치정보삭제</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/35</guid>
      <comments>https://nocklock.tistory.com/35#entry35comment</comments>
      <pubDate>Sun, 27 Sep 2026 08:30:53 +0900</pubDate>
    </item>
    <item>
      <title>ChatGPT만 쓰다가 Ollama를 직접 돌려봤다 &amp;mdash; 로컬 AI는 뭐가 달랐을까</title>
      <link>https://nocklock.tistory.com/32</link>
      <description>&lt;p data-end=&quot;242&quot; data-start=&quot;213&quot; data-ke-size=&quot;size16&quot;&gt;나는 그동안 AI를 거의 완성된 서비스로만 사용했다.&lt;/p&gt;
&lt;p data-end=&quot;300&quot; data-start=&quot;244&quot; data-ke-size=&quot;size16&quot;&gt;ChatGPT를 열고 질문한다.&lt;br /&gt;Claude에게 코드를 보여준다.&lt;br /&gt;답변이 오면 다시 개발한다.&lt;/p&gt;
&lt;p data-end=&quot;306&quot; data-start=&quot;302&quot; data-ke-size=&quot;size16&quot;&gt;편했다.&lt;/p&gt;
&lt;p data-end=&quot;363&quot; data-start=&quot;308&quot; data-ke-size=&quot;size16&quot;&gt;그래서 AI 모델을 직접 내 컴퓨터에서 돌린다는 것도 처음에는 생각보다 별일 아닐 거라고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;401&quot; data-start=&quot;365&quot; data-ke-size=&quot;size16&quot;&gt;모델 하나 받고, 실행하고, API처럼 연결하면 되는 것 아닐까.&lt;/p&gt;
&lt;p data-end=&quot;441&quot; data-start=&quot;403&quot; data-ke-size=&quot;size16&quot;&gt;보안렌즈를 만들면서 Ollama를 설치하기 전까지는 그렇게 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;441&quot; data-start=&quot;403&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 21일 오후 08_32_12.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xRWnY/dJMcafuB6aT/DlIQUSKJylnLT1YH6onWF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xRWnY/dJMcafuB6aT/DlIQUSKJylnLT1YH6onWF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xRWnY/dJMcafuB6aT/DlIQUSKJylnLT1YH6onWF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxRWnY%2FdJMcafuB6aT%2FDlIQUSKJylnLT1YH6onWF1%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; alt=&quot;Local AI&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 21일 오후 08_32_12.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-end=&quot;463&quot; data-start=&quot;443&quot; data-section-id=&quot;1caca9b&quot; data-ke-size=&quot;size26&quot;&gt;로컬 AI를 써보고 싶었던 이유&lt;/h2&gt;
&lt;p data-end=&quot;501&quot; data-start=&quot;465&quot; data-ke-size=&quot;size16&quot;&gt;보안렌즈는 이미지 안에 들어 있는 개인정보를 찾아주는 프로젝트다.&lt;/p&gt;
&lt;p data-end=&quot;557&quot; data-start=&quot;503&quot; data-ke-size=&quot;size16&quot;&gt;전화번호나 이메일 같은 텍스트뿐 아니라 이미지의 EXIF 정보, GPS 같은 데이터까지 확인한다.&lt;/p&gt;
&lt;p data-end=&quot;583&quot; data-start=&quot;559&quot; data-ke-size=&quot;size16&quot;&gt;만들다 보니 자연스럽게 이런 생각이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;646&quot; data-start=&quot;585&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개인정보를 검사하는 서비스인데, 그 개인정보가 다시 외부 AI 서버로 전달되는 건 조금 이상하지 않나?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;673&quot; data-start=&quot;648&quot; data-ke-size=&quot;size16&quot;&gt;물론 모든 기능을 AI로 처리할 필요는 없다.&lt;/p&gt;
&lt;p data-end=&quot;730&quot; data-start=&quot;675&quot; data-ke-size=&quot;size16&quot;&gt;정규식으로 찾을 수 있는 정보도 있고, OCR이나 메타데이터 분석만으로 처리할 수 있는 것도 있다.&lt;/p&gt;
&lt;p data-end=&quot;791&quot; data-start=&quot;732&quot; data-ke-size=&quot;size16&quot;&gt;그래도 AI를 붙여보고 싶었고, 이왕이면 데이터가 내 컴퓨터 밖으로 나가지 않는 구조도 경험해보고 싶었다.&lt;/p&gt;
&lt;p data-end=&quot;810&quot; data-start=&quot;793&quot; data-ke-size=&quot;size16&quot;&gt;그래서 Ollama를 설치했다.&lt;/p&gt;
&lt;h2 data-end=&quot;843&quot; data-start=&quot;812&quot; data-section-id=&quot;15dpab0&quot; data-ke-size=&quot;size26&quot;&gt;모델을 '사용하는 것'과 '돌리는 것'은 꽤 달랐다&lt;/h2&gt;
&lt;p data-end=&quot;869&quot; data-start=&quot;845&quot; data-ke-size=&quot;size16&quot;&gt;처음 받은 모델은 Gemma3:4b였다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;ollama pull gemma3:4b&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;952&quot; data-start=&quot;906&quot; data-ke-size=&quot;size16&quot;&gt;평소 ChatGPT를 사용할 때는 모델이 어디에서 실행되는지 크게 생각하지 않는다.&lt;/p&gt;
&lt;p data-end=&quot;984&quot; data-start=&quot;954&quot; data-ke-size=&quot;size16&quot;&gt;그런데 직접 모델을 내려받아 보니 느낌이 조금 달랐다.&lt;/p&gt;
&lt;p data-end=&quot;1041&quot; data-start=&quot;986&quot; data-ke-size=&quot;size16&quot;&gt;몇 GB짜리 모델 파일이 실제로 내 컴퓨터에 들어오고, 내 컴퓨터의 자원을 이용해서 답변을 만든다.&lt;/p&gt;
&lt;p data-end=&quot;1081&quot; data-start=&quot;1043&quot; data-ke-size=&quot;size16&quot;&gt;당연한 이야기인데 직접 해보기 전에는 별로 의식하지 않았던 부분이다.&lt;/p&gt;
&lt;p data-end=&quot;1128&quot; data-start=&quot;1083&quot; data-ke-size=&quot;size16&quot;&gt;ChatGPT에서 질문 하나를 입력할 때는 그 뒤에 있는 인프라를 볼 일이 없다.&lt;/p&gt;
&lt;p data-end=&quot;1166&quot; data-start=&quot;1130&quot; data-ke-size=&quot;size16&quot;&gt;Ollama를 사용하니 갑자기 그 아래쪽이 조금 보이기 시작했다.&lt;/p&gt;
&lt;h2 data-end=&quot;1188&quot; data-start=&quot;1168&quot; data-section-id=&quot;15fborq&quot; data-ke-size=&quot;size26&quot;&gt;첫 번째 문제는 AI가 아니었다&lt;/h2&gt;
&lt;p data-end=&quot;1225&quot; data-start=&quot;1190&quot; data-ke-size=&quot;size16&quot;&gt;재미있게도 처음 막힌 것은 모델의 성능이나 프롬프트가 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;1233&quot; data-start=&quot;1227&quot; data-ke-size=&quot;size16&quot;&gt;환경이었다.&lt;/p&gt;
&lt;p data-end=&quot;1290&quot; data-start=&quot;1235&quot; data-ke-size=&quot;size16&quot;&gt;내 PC에서는 CUDA 관련 toolchain 문제가 생겼고 결국 CPU로 돌리는 방향으로 바꿨다.&lt;/p&gt;
&lt;p data-end=&quot;1323&quot; data-start=&quot;1292&quot; data-ke-size=&quot;size16&quot;&gt;그 다음에는 Ollama 서버를 직접 실행해보려고 했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;ollama serve&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1366&quot; data-start=&quot;1351&quot; data-ke-size=&quot;size16&quot;&gt;그런데 또 실행되지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;1417&quot; data-start=&quot;1368&quot; data-ke-size=&quot;size16&quot;&gt;이유를 찾아보니 Ollama가 사용하는 기본 포트인 11434가 이미 사용 중이었다.&lt;/p&gt;
&lt;p data-end=&quot;1440&quot; data-start=&quot;1419&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 뭔가 잘못 설치한 줄 알았다.&lt;/p&gt;
&lt;p data-end=&quot;1499&quot; data-start=&quot;1442&quot; data-ke-size=&quot;size16&quot;&gt;알고 보니 Ollama가 이미 실행되고 있었고, 나는 실행 중인 서버를 하나 더 띄우려고 하고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1539&quot; data-start=&quot;1501&quot; data-ke-size=&quot;size16&quot;&gt;AI 모델을 연결하려고 시작했는데 실제로 내가 보고 있었던 것은 결국&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1576&quot; data-start=&quot;1541&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1547&quot; data-start=&quot;1541&quot; data-section-id=&quot;az4zcc&quot;&gt;프로세스&lt;/li&gt;
&lt;li data-end=&quot;1552&quot; data-start=&quot;1548&quot; data-section-id=&quot;yigwho&quot;&gt;포트&lt;/li&gt;
&lt;li data-end=&quot;1557&quot; data-start=&quot;1553&quot; data-section-id=&quot;yim8c0&quot;&gt;서버&lt;/li&gt;
&lt;li data-end=&quot;1568&quot; data-start=&quot;1558&quot; data-section-id=&quot;g9439o&quot;&gt;GPU와 CPU&lt;/li&gt;
&lt;li data-end=&quot;1576&quot; data-start=&quot;1569&quot; data-section-id=&quot;vo24ww&quot;&gt;실행 환경&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1598&quot; data-start=&quot;1578&quot; data-ke-size=&quot;size16&quot;&gt;같은 아주 평범한 개발 문제들이었다.&lt;/p&gt;
&lt;p data-end=&quot;1620&quot; data-start=&quot;1600&quot; data-ke-size=&quot;size16&quot;&gt;이 부분은 따로 개발노트로 정리했다.&lt;/p&gt;
&lt;blockquote data-end=&quot;1677&quot; data-start=&quot;1622&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1677&quot; data-start=&quot;1624&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Ollama 11434 포트 충돌 해결 &amp;mdash; ollama serve가 실행되지 않았던 이유&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1714&quot; data-start=&quot;1679&quot; data-ke-size=&quot;size16&quot;&gt;AI를 사용한다고 해서 기존 개발 지식이 사라지는 건 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;1731&quot; data-start=&quot;1716&quot; data-ke-size=&quot;size16&quot;&gt;오히려 그 반대에 가까웠다.&lt;/p&gt;
&lt;h2 data-end=&quot;1759&quot; data-start=&quot;1733&quot; data-section-id=&quot;woyiji&quot; data-ke-size=&quot;size26&quot;&gt;Spring Boot에서 실제로 연결해봤다&lt;/h2&gt;
&lt;p data-end=&quot;1816&quot; data-start=&quot;1761&quot; data-ke-size=&quot;size16&quot;&gt;보안렌즈는 Spring Boot로 만들고 있었기 때문에 Ollama도 결국 서버에서 호출해야 했다.&lt;/p&gt;
&lt;p data-end=&quot;1839&quot; data-start=&quot;1818&quot; data-ke-size=&quot;size16&quot;&gt;구조 자체는 생각보다 특별하지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;1886&quot; data-start=&quot;1841&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot가 로컬에서 실행되고 있는 Ollama 서버에 요청을 보내고,&lt;/p&gt;
&lt;p data-end=&quot;1916&quot; data-start=&quot;1888&quot; data-ke-size=&quot;size16&quot;&gt;Ollama가 모델을 실행한 다음 결과를 돌려준다.&lt;/p&gt;
&lt;p data-end=&quot;1929&quot; data-start=&quot;1918&quot; data-ke-size=&quot;size16&quot;&gt;대략 이런 구조였다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;사용자
  &amp;darr;
Spring Boot
  &amp;darr;
Ollama
  &amp;darr;
Gemma3:4b&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2017&quot; data-start=&quot;1989&quot; data-ke-size=&quot;size16&quot;&gt;여기까지 만들고 나니 조금 재미있는 느낌이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;2101&quot; data-start=&quot;2019&quot; data-ke-size=&quot;size16&quot;&gt;브라우저에서 ChatGPT를 사용하는 것과 AI 모델을 내 애플리케이션의 구성 요소 하나로 넣는 것은 같은 AI를 쓰는 일이지만 경험은 꽤 달랐다.&lt;/p&gt;
&lt;p data-end=&quot;2131&quot; data-start=&quot;2103&quot; data-ke-size=&quot;size16&quot;&gt;전자는 &lt;b&gt;AI 서비스를 사용하는 것&lt;/b&gt;에 가깝고,&lt;/p&gt;
&lt;p data-end=&quot;2171&quot; data-start=&quot;2133&quot; data-ke-size=&quot;size16&quot;&gt;후자는 &lt;b&gt;AI가 포함된 시스템을 만드는 것&lt;/b&gt;에 조금 더 가까웠다.&lt;/p&gt;
&lt;h2 data-end=&quot;2197&quot; data-start=&quot;2173&quot; data-section-id=&quot;a2mtmt&quot; data-ke-size=&quot;size26&quot;&gt;로컬 AI가 무조건 좋은 것은 아니었다&lt;/h2&gt;
&lt;p data-end=&quot;2237&quot; data-start=&quot;2199&quot; data-ke-size=&quot;size16&quot;&gt;직접 돌려보니 로컬 AI가 모든 상황의 정답이라고 생각되지는 않았다.&lt;/p&gt;
&lt;p data-end=&quot;2248&quot; data-start=&quot;2239&quot; data-ke-size=&quot;size16&quot;&gt;장점은 분명했다.&lt;/p&gt;
&lt;p data-end=&quot;2269&quot; data-start=&quot;2250&quot; data-ke-size=&quot;size16&quot;&gt;가장 먼저 떠오르는 것은 데이터다.&lt;/p&gt;
&lt;p data-end=&quot;2315&quot; data-start=&quot;2271&quot; data-ke-size=&quot;size16&quot;&gt;처리할 정보를 외부 AI 서비스로 보내지 않고 내 환경 안에서 처리할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2342&quot; data-start=&quot;2317&quot; data-ke-size=&quot;size16&quot;&gt;API 비용도 다른 방식으로 생각할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2370&quot; data-start=&quot;2344&quot; data-ke-size=&quot;size16&quot;&gt;반대로 내가 직접 신경 써야 할 것도 많아졌다.&lt;/p&gt;
&lt;p data-end=&quot;2383&quot; data-start=&quot;2372&quot; data-ke-size=&quot;size16&quot;&gt;모델을 받아야 하고,&lt;/p&gt;
&lt;p data-end=&quot;2401&quot; data-start=&quot;2385&quot; data-ke-size=&quot;size16&quot;&gt;컴퓨터 자원을 사용해야 하고,&lt;/p&gt;
&lt;p data-end=&quot;2418&quot; data-start=&quot;2403&quot; data-ke-size=&quot;size16&quot;&gt;실행 상태도 확인해야 하고,&lt;/p&gt;
&lt;p data-end=&quot;2446&quot; data-start=&quot;2420&quot; data-ke-size=&quot;size16&quot;&gt;문제가 생기면 포트와 프로세스도 확인해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;2479&quot; data-start=&quot;2448&quot; data-ke-size=&quot;size16&quot;&gt;하드웨어에 따라 사용할 수 있는 모델의 크기도 달라진다.&lt;/p&gt;
&lt;p data-end=&quot;2524&quot; data-start=&quot;2481&quot; data-ke-size=&quot;size16&quot;&gt;클라우드 AI에서는 누군가 대신 해주던 일들이 로컬에서는 다시 내 일이 된다.&lt;/p&gt;
&lt;p data-end=&quot;2557&quot; data-start=&quot;2526&quot; data-ke-size=&quot;size16&quot;&gt;그래서 지금은 둘 중 하나가 더 좋다고 생각하지 않는다.&lt;/p&gt;
&lt;p data-end=&quot;2604&quot; data-start=&quot;2559&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;어디에서 AI를 돌릴 것인가도 결국 서비스의 요구사항 중 하나인 것 같다.&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;2627&quot; data-start=&quot;2606&quot; data-section-id=&quot;1t5uet0&quot; data-ke-size=&quot;size26&quot;&gt;그런데 한 가지는 확실히 달라졌다&lt;/h2&gt;
&lt;p data-end=&quot;2669&quot; data-start=&quot;2629&quot; data-ke-size=&quot;size16&quot;&gt;Ollama를 설치하기 전까지 나에게 AI는 거의 항상 이런 모습이었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;나 &amp;rarr; ChatGPT&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2710&quot; data-start=&quot;2696&quot; data-ke-size=&quot;size16&quot;&gt;질문을 하고 답을 받는다.&lt;/p&gt;
&lt;p data-end=&quot;2727&quot; data-start=&quot;2712&quot; data-ke-size=&quot;size16&quot;&gt;지금은 조금 다르게 보인다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;서비스
 ├─ 일반 코드
 ├─ 데이터 처리
 ├─ 규칙 기반 분석
 └─ AI 모델&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2839&quot; data-start=&quot;2790&quot; data-ke-size=&quot;size16&quot;&gt;AI가 애플리케이션 안에 들어갈 수 있는 여러 구성 요소 중 하나처럼 느껴지기 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;2862&quot; data-start=&quot;2841&quot; data-ke-size=&quot;size16&quot;&gt;모든 것을 AI에게 맡길 필요도 없고,&lt;/p&gt;
&lt;p data-end=&quot;2892&quot; data-start=&quot;2864&quot; data-ke-size=&quot;size16&quot;&gt;반대로 모든 것을 직접 코드로 처리할 필요도 없다.&lt;/p&gt;
&lt;p data-end=&quot;2979&quot; data-start=&quot;2894&quot; data-ke-size=&quot;size16&quot;&gt;보안렌즈를 만들면서도 전화번호나 이메일처럼 명확하게 찾을 수 있는 정보는 기존 방식으로 처리하고, AI가 필요한 부분만 별도로 붙이는 방향으로 만들었다.&lt;/p&gt;
&lt;p data-end=&quot;3041&quot; data-start=&quot;2981&quot; data-ke-size=&quot;size16&quot;&gt;AI를 많이 쓰는 것보다 &lt;b&gt;어디에 써야 하는지를 정하는 게 더 중요하다는 생각&lt;/b&gt;도 조금씩 들기 시작했다.&lt;/p&gt;
&lt;h2 data-end=&quot;3071&quot; data-start=&quot;3043&quot; data-section-id=&quot;84jn5w&quot; data-ke-size=&quot;size26&quot;&gt;직접 돌려보니 AI가 조금 덜 마법처럼 보였다&lt;/h2&gt;
&lt;p data-end=&quot;3099&quot; data-start=&quot;3073&quot; data-ke-size=&quot;size16&quot;&gt;ChatGPT만 사용할 때는 결과만 보게 된다.&lt;/p&gt;
&lt;p data-end=&quot;3133&quot; data-start=&quot;3101&quot; data-ke-size=&quot;size16&quot;&gt;Ollama를 사용하면서는 그 앞뒤를 조금 더 보게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;3142&quot; data-start=&quot;3135&quot; data-ke-size=&quot;size16&quot;&gt;모델을 받고,&lt;/p&gt;
&lt;p data-end=&quot;3153&quot; data-start=&quot;3144&quot; data-ke-size=&quot;size16&quot;&gt;서버를 실행하고,&lt;/p&gt;
&lt;p data-end=&quot;3164&quot; data-start=&quot;3155&quot; data-ke-size=&quot;size16&quot;&gt;포트를 확인하고,&lt;/p&gt;
&lt;p data-end=&quot;3180&quot; data-start=&quot;3166&quot; data-ke-size=&quot;size16&quot;&gt;애플리케이션에서 호출한다.&lt;/p&gt;
&lt;p data-end=&quot;3204&quot; data-start=&quot;3182&quot; data-ke-size=&quot;size16&quot;&gt;그러다 문제가 생기면 다시 로그를 본다.&lt;/p&gt;
&lt;p data-end=&quot;3215&quot; data-start=&quot;3206&quot; data-ke-size=&quot;size16&quot;&gt;결국 개발이었다.&lt;/p&gt;
&lt;p data-end=&quot;3251&quot; data-start=&quot;3217&quot; data-ke-size=&quot;size16&quot;&gt;AI라고 해서 완전히 새로운 세계가 하나 생긴 것은 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;3312&quot; data-start=&quot;3253&quot; data-ke-size=&quot;size16&quot;&gt;내가 알고 있던 서버, API, 프로세스, 하드웨어 위에 새로운 구성 요소 하나가 들어온 느낌에 가까웠다.&lt;/p&gt;
&lt;p data-end=&quot;3342&quot; data-start=&quot;3314&quot; data-ke-size=&quot;size16&quot;&gt;그래서 오히려 AI가 예전보다 조금 덜 막연해졌다.&lt;/p&gt;
&lt;p data-end=&quot;3376&quot; data-start=&quot;3344&quot; data-ke-size=&quot;size16&quot;&gt;아직 로컬 LLM을 제대로 안다고 말하기에는 한참 멀었다.&lt;/p&gt;
&lt;p data-end=&quot;3389&quot; data-start=&quot;3378&quot; data-ke-size=&quot;size16&quot;&gt;그래도 적어도 이제는&lt;/p&gt;
&lt;p data-end=&quot;3450&quot; data-start=&quot;3391&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;AI를 사용해봤다&amp;rdquo;와 &amp;ldquo;AI를 내 서비스 안에서 직접 돌려봤다&amp;rdquo; 사이에는 꽤 큰 차이가 있다는 것&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3463&quot; data-start=&quot;3452&quot; data-ke-size=&quot;size16&quot;&gt;정도는 알 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;3511&quot; data-start=&quot;3465&quot; data-ke-size=&quot;size16&quot;&gt;그리고 이건 아마 앞으로 다른 서비스를 만들 때도 계속 써먹게 될 경험일 것 같다.&lt;/p&gt;</description>
      <category>AI TOOLS</category>
      <category>AI 개발</category>
      <category>ChatGPT</category>
      <category>gemma3</category>
      <category>local llm</category>
      <category>ollama</category>
      <category>spring boot</category>
      <category>개발자 AI</category>
      <category>로컬llm</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/32</guid>
      <comments>https://nocklock.tistory.com/32#entry32comment</comments>
      <pubDate>Sat, 26 Sep 2026 08:30:43 +0900</pubDate>
    </item>
    <item>
      <title>Ollama 11434 포트 충돌 해결 &amp;mdash; ollama serve가 실행되지 않았던 이유</title>
      <link>https://nocklock.tistory.com/31</link>
      <description>&lt;p data-end=&quot;191&quot; data-start=&quot;152&quot; data-ke-size=&quot;size16&quot;&gt;Ollama를 설치하고 모델을 받은 뒤 서버를 직접 실행해보려고 했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 21일 오후 12_23_30.png&quot; data-origin-width=&quot;1448&quot; data-origin-height=&quot;1086&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bErKmw/dJMcahFVM48/aOzaaaDAV0oy4l8EdGGc51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bErKmw/dJMcahFVM48/aOzaaaDAV0oy4l8EdGGc51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bErKmw/dJMcahFVM48/aOzaaaDAV0oy4l8EdGGc51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbErKmw%2FdJMcahFVM48%2FaOzaaaDAV0oy4l8EdGGc51%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; alt=&quot;서버충돌&quot; loading=&quot;lazy&quot; width=&quot;1448&quot; height=&quot;1086&quot; data-filename=&quot;ChatGPT Image 2026년 9월 21일 오후 12_23_30.png&quot; data-origin-width=&quot;1448&quot; data-origin-height=&quot;1086&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;ollama serve&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;272&quot; data-start=&quot;219&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;272&quot; data-start=&quot;219&quot; data-ke-size=&quot;size16&quot;&gt;그런데 서버가 정상적으로 시작되는 대신 11434 포트가 이미 사용 중이라는 오류가 나왔다.&lt;/p&gt;
&lt;p data-end=&quot;293&quot; data-start=&quot;274&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 또 포트 충돌인가 싶었다.&lt;/p&gt;
&lt;p data-end=&quot;370&quot; data-start=&quot;295&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot를 실행하면서 8080 포트 충돌을 겪은 적이 있었기 때문에 이번에도 다른 프로그램이 포트를 잡고 있다고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;388&quot; data-start=&quot;372&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이번에는 조금 달랐다.&lt;/p&gt;
&lt;p data-end=&quot;446&quot; data-start=&quot;390&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다른 프로그램이 Ollama의 자리를 차지한 게 아니라, Ollama가 이미 실행되고 있었다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;451&quot; data-start=&quot;448&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;484&quot; data-start=&quot;453&quot; data-section-id=&quot;1pmovq4&quot; data-ke-size=&quot;size26&quot;&gt;Ollama는 기본적으로 11434 포트를 사용한다&lt;/h2&gt;
&lt;p data-end=&quot;536&quot; data-start=&quot;486&quot; data-ke-size=&quot;size16&quot;&gt;Ollama는 로컬에서 API 서버를 실행할 때 기본적으로 11434 포트를 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;579&quot; data-start=&quot;538&quot; data-ke-size=&quot;size16&quot;&gt;그래서 로컬에서 Ollama API를 사용할 때 기본 주소는 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;http://localhost:11434&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;643&quot; data-start=&quot;617&quot; data-ke-size=&quot;size16&quot;&gt;문제는 이미 Ollama가 실행되고 있는데 다시&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;ollama serve&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;682&quot; data-start=&quot;671&quot; data-ke-size=&quot;size16&quot;&gt;를 실행한 경우였다.&lt;/p&gt;
&lt;p data-end=&quot;770&quot; data-start=&quot;684&quot; data-ke-size=&quot;size16&quot;&gt;이미 실행 중인 Ollama가 11434 포트를 사용하고 있으니, 새로 실행한 ollama serve가 같은 포트를 다시 사용할 수 없었던 것이다.&lt;/p&gt;
&lt;hr data-end=&quot;775&quot; data-start=&quot;772&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;799&quot; data-start=&quot;777&quot; data-section-id=&quot;1hb4cp5&quot; data-ke-size=&quot;size26&quot;&gt;처음에는 서버가 안 켜진 줄 알았다&lt;/h2&gt;
&lt;p data-end=&quot;818&quot; data-start=&quot;801&quot; data-ke-size=&quot;size16&quot;&gt;내가 헷갈렸던 부분은 여기였다.&lt;/p&gt;
&lt;p data-end=&quot;863&quot; data-start=&quot;820&quot; data-ke-size=&quot;size16&quot;&gt;ollama serve를 실행해야 Ollama 서버가 시작된다고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;906&quot; data-start=&quot;865&quot; data-ke-size=&quot;size16&quot;&gt;그래서 명령어를 실행했는데 포트가 사용 중이라는 메시지가 나오니 자연스럽게&lt;/p&gt;
&lt;blockquote data-end=&quot;931&quot; data-start=&quot;908&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;931&quot; data-start=&quot;910&quot; data-ke-size=&quot;size16&quot;&gt;Ollama 서버 실행에 실패한 건가?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;941&quot; data-start=&quot;933&quot; data-ke-size=&quot;size16&quot;&gt;라고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;959&quot; data-start=&quot;943&quot; data-ke-size=&quot;size16&quot;&gt;그런데 실제 상황은 반대였다.&lt;/p&gt;
&lt;p data-end=&quot;1007&quot; data-start=&quot;961&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이미 서버가 실행되고 있었기 때문에 두 번째 서버를 띄울 수 없었던 것이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1033&quot; data-start=&quot;1009&quot; data-ke-size=&quot;size16&quot;&gt;생각해보면 오류 메시지 자체는 꽤 정확했다.&lt;/p&gt;
&lt;p data-end=&quot;1080&quot; data-start=&quot;1035&quot; data-ke-size=&quot;size16&quot;&gt;11434를 사용할 수 없는 게 문제가 아니라, 누군가 이미 사용하고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1102&quot; data-start=&quot;1082&quot; data-ke-size=&quot;size16&quot;&gt;그리고 그 누군가가 Ollama였다.&lt;/p&gt;
&lt;hr data-end=&quot;1107&quot; data-start=&quot;1104&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1136&quot; data-start=&quot;1109&quot; data-section-id=&quot;7th22e&quot; data-ke-size=&quot;size26&quot;&gt;11434 포트를 누가 사용하고 있는지 확인&lt;/h2&gt;
&lt;p data-end=&quot;1189&quot; data-start=&quot;1138&quot; data-ke-size=&quot;size16&quot;&gt;Windows에서는 다음 명령어로 11434 포트를 사용하는 프로세스를 확인할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;netstat -ano | findstr :11434&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1278&quot; data-start=&quot;1234&quot; data-ke-size=&quot;size16&quot;&gt;정상적으로 프로세스가 떠 있다면 해당 포트를 사용하는 항목과 PID가 표시된다.&lt;/p&gt;
&lt;p data-end=&quot;1312&quot; data-start=&quot;1280&quot; data-ke-size=&quot;size16&quot;&gt;PID를 확인한 뒤에는 어떤 프로세스인지 확인할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;tasklist | findstr PID번호&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1412&quot; data-start=&quot;1352&quot; data-ke-size=&quot;size16&quot;&gt;여기에서 Ollama 관련 프로세스가 확인된다면 굳이 ollama serve를 다시 실행할 필요가 없다.&lt;/p&gt;
&lt;hr data-end=&quot;1417&quot; data-start=&quot;1414&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1442&quot; data-start=&quot;1419&quot; data-section-id=&quot;1j95pms&quot; data-ke-size=&quot;size26&quot;&gt;서버가 실제로 실행 중인지 확인해봤다&lt;/h2&gt;
&lt;p data-end=&quot;1502&quot; data-start=&quot;1444&quot; data-ke-size=&quot;size16&quot;&gt;포트를 사용하고 있다는 사실만으로 판단하기보다 Ollama API가 실제로 응답하는지도 확인할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1531&quot; data-start=&quot;1504&quot; data-ke-size=&quot;size16&quot;&gt;브라우저나 API 도구에서 다음 주소로 접근한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;http://localhost:11434&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1608&quot; data-start=&quot;1569&quot; data-ke-size=&quot;size16&quot;&gt;또는 Ollama API를 직접 호출해 모델 목록을 확인할 수도 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;http://localhost:11434/api/tags&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1692&quot; data-start=&quot;1655&quot; data-ke-size=&quot;size16&quot;&gt;정상적인 응답이 온다면 Ollama 서버는 이미 실행 중인 것이다.&lt;/p&gt;
&lt;p data-end=&quot;1768&quot; data-start=&quot;1694&quot; data-ke-size=&quot;size16&quot;&gt;이 상태에서는 Spring Boot 같은 다른 애플리케이션에서도 localhost:11434를 통해 Ollama를 호출하면 된다.&lt;/p&gt;
&lt;hr data-end=&quot;1773&quot; data-start=&quot;1770&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1810&quot; data-start=&quot;1775&quot; data-section-id=&quot;18be23a&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;결국 ollama serve를 또 실행할 필요가 없었다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-end=&quot;1844&quot; data-start=&quot;1812&quot; data-ke-size=&quot;size16&quot;&gt;이번 문제는 서버를 새로 띄우는 것으로 해결한 게 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1895&quot; data-start=&quot;1846&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이미 실행되고 있는 서버를 다시 실행하려고 했다는 사실을 알아낸 것으로 해결됐다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1946&quot; data-start=&quot;1897&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot에서 겪었던 8080 포트 충돌 때는 포트를 8081로 변경했다.&lt;/p&gt;
&lt;p data-end=&quot;1992&quot; data-start=&quot;1948&quot; data-ke-size=&quot;size16&quot;&gt;하지만 Ollama에서는 굳이 11434를 다른 포트로 바꿀 이유가 없었다.&lt;/p&gt;
&lt;p data-end=&quot;2031&quot; data-start=&quot;1994&quot; data-ke-size=&quot;size16&quot;&gt;이미 정상적으로 Ollama가 그 포트를 사용하고 있었기 때문이다.&lt;/p&gt;
&lt;hr data-end=&quot;2036&quot; data-start=&quot;2033&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2069&quot; data-start=&quot;2038&quot; data-section-id=&quot;cybkrm&quot; data-ke-size=&quot;size26&quot;&gt;포트 충돌이라고 해서 항상 포트를 바꿀 필요는 없다&lt;/h2&gt;
&lt;p data-end=&quot;2142&quot; data-start=&quot;2071&quot; data-ke-size=&quot;size16&quot;&gt;개발하다 보면 address already in use나 port already in use 같은 메시지를 자주 만난다.&lt;/p&gt;
&lt;p data-end=&quot;2154&quot; data-start=&quot;2144&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 자연스럽게&lt;/p&gt;
&lt;blockquote data-end=&quot;2172&quot; data-start=&quot;2156&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2172&quot; data-start=&quot;2158&quot; data-ke-size=&quot;size16&quot;&gt;다른 포트로 바꾸면 되나?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2185&quot; data-start=&quot;2174&quot; data-ke-size=&quot;size16&quot;&gt;부터 생각하게 된다.&lt;/p&gt;
&lt;p data-end=&quot;2223&quot; data-start=&quot;2187&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이번 경험에서는 순서를 조금 바꿔야 한다는 걸 알게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;2262&quot; data-start=&quot;2225&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;포트를 바꾸기 전에 누가 사용하고 있는지 먼저 확인하는 것.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2312&quot; data-start=&quot;2264&quot; data-ke-size=&quot;size16&quot;&gt;원래 실행하려던 프로그램이 이미 정상적으로 사용하고 있다면 아무것도 바꿀 필요가 없다.&lt;/p&gt;
&lt;p data-end=&quot;2369&quot; data-start=&quot;2314&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 11434가 문제였던 게 아니라, 내가 Ollama를 두 번 실행하려고 했던 게 문제였다.&lt;/p&gt;
&lt;hr data-end=&quot;2374&quot; data-start=&quot;2371&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2381&quot; data-start=&quot;2376&quot; data-section-id=&quot;1melx8&quot; data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;
&lt;p data-end=&quot;2448&quot; data-start=&quot;2383&quot; data-ke-size=&quot;size16&quot;&gt;ollama serve 실행 중 11434 포트가 이미 사용 중이라는 오류가 나온다면 먼저 다음을 확인하면 된다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;2610&quot; data-start=&quot;2450&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;2481&quot; data-start=&quot;2450&quot; data-section-id=&quot;l04pxn&quot;&gt;11434 포트를 사용하는 프로세스를 확인한다.&lt;/li&gt;
&lt;li data-end=&quot;2508&quot; data-start=&quot;2482&quot; data-section-id=&quot;1h1zsa0&quot;&gt;Ollama가 이미 실행 중인지 확인한다.&lt;/li&gt;
&lt;li data-end=&quot;2562&quot; data-start=&quot;2509&quot; data-section-id=&quot;1y7c138&quot;&gt;localhost:11434 또는 Ollama API가 정상적으로 응답하는지 확인한다.&lt;/li&gt;
&lt;li data-end=&quot;2610&quot; data-start=&quot;2563&quot; data-section-id=&quot;x1ths7&quot;&gt;이미 정상 실행 중이라면 ollama serve를 다시 실행할 필요가 없다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;2680&quot; data-start=&quot;2612&quot; data-ke-size=&quot;size16&quot;&gt;내 경우에는 &lt;b&gt;Ollama가 이미 실행 중인 상태에서 ollama serve를 한 번 더 실행한 것이 원인&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p data-end=&quot;2706&quot; data-start=&quot;2682&quot; data-ke-size=&quot;size16&quot;&gt;포트를 바꾸지 않고 그대로 개발을 계속했다.&lt;/p&gt;
&lt;hr data-end=&quot;2711&quot; data-start=&quot;2708&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2727&quot; data-start=&quot;2713&quot; data-section-id=&quot;er48m&quot; data-ke-size=&quot;size26&quot;&gt;같이 읽으면 좋은 글&lt;/h2&gt;
&lt;p data-end=&quot;2777&quot; data-start=&quot;2729&quot; data-ke-size=&quot;size16&quot;&gt;이번 문제처럼 로컬 개발환경을 구성하면서 만난 문제들은 따로 개발노트로 정리하고 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3056&quot; data-start=&quot;2779&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2879&quot; data-start=&quot;2779&quot; data-section-id=&quot;1e372sy&quot;&gt;&lt;a href=&quot;https://nocklock.tistory.com/24&quot; data-end=&quot;2879&quot; data-start=&quot;2781&quot;&gt;Spring Boot Docker 배포 방법 &amp;mdash; Windows/WSL부터 Railway까지 직접 해보며 막힌 것들&lt;/a&gt;&lt;/li&gt;
&lt;li data-end=&quot;2972&quot; data-start=&quot;2880&quot; data-section-id=&quot;ursmxk&quot;&gt;&lt;a href=&quot;https://nocklock.tistory.com/23&quot; data-end=&quot;2972&quot; data-start=&quot;2882&quot;&gt;Git status에서 모든 파일이 modified로 뜰 때 &amp;mdash; WSL에서 만난 CRLF/LF 문제&lt;/a&gt;&lt;/li&gt;
&lt;li data-end=&quot;3056&quot; data-start=&quot;2973&quot; data-section-id=&quot;1y3sbsk&quot;&gt;&lt;a href=&quot;https://nocklock.tistory.com/16?utm_source=chatgpt.com&quot; data-end=&quot;3056&quot; data-start=&quot;2975&quot;&gt;내 컴퓨터에서는 잘 되는데, 다른 사람도 쓸 수 있어야 했다 | RE:개발자 #10&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발 노트</category>
      <category>11434</category>
      <category>ollama</category>
      <category>ollamaServe</category>
      <category>개발노트</category>
      <category>로컬llm</category>
      <category>포트충돌</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/31</guid>
      <comments>https://nocklock.tistory.com/31#entry31comment</comments>
      <pubDate>Fri, 25 Sep 2026 20:30:08 +0900</pubDate>
    </item>
    <item>
      <title>개발자인 내가 테스트하면 이상하게 잘 된다 | RE:개발자 #13</title>
      <link>https://nocklock.tistory.com/20</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오전 12_19_08.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rmDFp/dJMcafO37hg/e6hsajLTWbaksoWicGpedK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rmDFp/dJMcafO37hg/e6hsajLTWbaksoWicGpedK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rmDFp/dJMcafO37hg/e6hsajLTWbaksoWicGpedK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrmDFp%2FdJMcafO37hg%2Fe6hsajLTWbaksoWicGpedK%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; alt=&quot;Bug&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오전 12_19_08.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;142&quot; data-start=&quot;133&quot; data-ke-size=&quot;size16&quot;&gt;배포까지 끝났다.&lt;/p&gt;
&lt;p data-end=&quot;194&quot; data-start=&quot;144&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터에서만 돌아가던 화면이 이제는 URL만 보내면 다른 사람도 사용할 수 있게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;194&quot; data-start=&quot;144&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 서비스를 실제로 배포하면서 겪었던 과정은 이전 글인 &lt;/span&gt;&lt;a href=&quot;https://nocklock.tistory.com/19&quot;&gt;&lt;b&gt;&lt;span&gt;내 컴퓨터에서는 잘 됐는데요 | RE:개발자 #12&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span&gt; 에 따로 적어뒀다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;194&quot; data-start=&quot;144&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;215&quot; data-start=&quot;196&quot; data-ke-size=&quot;size16&quot;&gt;여기까지 오니까 조금 안심이 됐다.&lt;/p&gt;
&lt;p data-end=&quot;261&quot; data-start=&quot;217&quot; data-ke-size=&quot;size16&quot;&gt;개발도 했고, 테스트도 했고, 배포도 했으니 이제 꽤 괜찮은 상태라고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;305&quot; data-start=&quot;263&quot; data-ke-size=&quot;size16&quot;&gt;그런데 배포된 서비스를 다시 이것저것 눌러보다가 바로 문제를 하나 발견했다.&lt;/p&gt;
&lt;p data-end=&quot;350&quot; data-start=&quot;307&quot; data-ke-size=&quot;size16&quot;&gt;평범한 사진을 하나 넣었는데, 일부 기능이 내가 생각한 대로 동작하지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;366&quot; data-start=&quot;352&quot; data-ke-size=&quot;size16&quot;&gt;순간 이런 생각이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;399&quot; data-start=&quot;368&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;분명 테스트 많이 했는데 왜 이걸 이제 발견했지?&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;404&quot; data-start=&quot;401&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;424&quot; data-start=&quot;406&quot; data-ke-size=&quot;size26&quot;&gt;테스트를 안 한 건 아니었다&lt;/h2&gt;
&lt;p data-end=&quot;438&quot; data-start=&quot;426&quot; data-ke-size=&quot;size16&quot;&gt;오히려 꽤 많이 했다.&lt;/p&gt;
&lt;p data-end=&quot;456&quot; data-start=&quot;440&quot; data-ke-size=&quot;size16&quot;&gt;사진을 바꿔가면서 분석해보고,&lt;/p&gt;
&lt;p data-end=&quot;476&quot; data-start=&quot;458&quot; data-ke-size=&quot;size16&quot;&gt;결과가 제대로 나오는지 확인하고,&lt;/p&gt;
&lt;p data-end=&quot;490&quot; data-start=&quot;478&quot; data-ke-size=&quot;size16&quot;&gt;화면도 계속 눌러봤다.&lt;/p&gt;
&lt;p data-end=&quot;513&quot; data-start=&quot;492&quot; data-ke-size=&quot;size16&quot;&gt;문제가 있으면 고치고 다시 테스트했다.&lt;/p&gt;
&lt;p data-end=&quot;540&quot; data-start=&quot;515&quot; data-ke-size=&quot;size16&quot;&gt;그래서 나름대로는 충분히 확인했다고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;575&quot; data-start=&quot;542&quot; data-ke-size=&quot;size16&quot;&gt;그런데 돌이켜보니 내가 테스트했던 방식에는 공통점이 있었다.&lt;/p&gt;
&lt;p data-end=&quot;609&quot; data-start=&quot;577&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기능이 잘 동작할 만한 상황을 계속 만들고 있었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;641&quot; data-start=&quot;611&quot; data-ke-size=&quot;size16&quot;&gt;분석 기능을 테스트하니까 분석할 만한 데이터를 넣었고,&lt;/p&gt;
&lt;p data-end=&quot;685&quot; data-start=&quot;643&quot; data-ke-size=&quot;size16&quot;&gt;특정 정보를 찾는 기능을 만들었으니까 그 정보가 들어 있는 이미지를 넣었다.&lt;/p&gt;
&lt;p data-end=&quot;696&quot; data-start=&quot;687&quot; data-ke-size=&quot;size16&quot;&gt;당연한 행동이다.&lt;/p&gt;
&lt;p data-end=&quot;732&quot; data-start=&quot;698&quot; data-ke-size=&quot;size16&quot;&gt;문제는 실제 사용자가 꼭 그렇게 사용하지는 않는다는 것이었다.&lt;/p&gt;
&lt;hr data-end=&quot;737&quot; data-start=&quot;734&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;762&quot; data-start=&quot;739&quot; data-ke-size=&quot;size26&quot;&gt;아무것도 발견되지 않는 것도 정상이다&lt;/h2&gt;
&lt;p data-end=&quot;780&quot; data-start=&quot;764&quot; data-ke-size=&quot;size16&quot;&gt;이번에 놓친 부분도 비슷했다.&lt;/p&gt;
&lt;p data-end=&quot;819&quot; data-start=&quot;782&quot; data-ke-size=&quot;size16&quot;&gt;나는 무언가가 탐지되어야 기능이 제대로 동작했다고 생각하고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;826&quot; data-start=&quot;821&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;개인정보 2건 발견
위험 정보 확인
분석 완료&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;894&quot; data-start=&quot;867&quot; data-ke-size=&quot;size16&quot;&gt;이런 결과가 나오면 자연스럽게 성공처럼 느껴졌다.&lt;/p&gt;
&lt;p data-end=&quot;899&quot; data-start=&quot;896&quot; data-ke-size=&quot;size16&quot;&gt;반대로&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;발견된 정보 0건&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;961&quot; data-start=&quot;924&quot; data-ke-size=&quot;size16&quot;&gt;이라고 나오면 어딘가 기능을 제대로 못 한 것 같은 느낌이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;983&quot; data-start=&quot;963&quot; data-ke-size=&quot;size16&quot;&gt;그런데 생각해보면 전혀 그렇지 않다.&lt;/p&gt;
&lt;p data-end=&quot;1001&quot; data-start=&quot;985&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 정상적으로 분석했고,&lt;/p&gt;
&lt;p data-end=&quot;1014&quot; data-start=&quot;1003&quot; data-ke-size=&quot;size16&quot;&gt;확인할 정보가 없어서&lt;/p&gt;
&lt;p data-end=&quot;1051&quot; data-start=&quot;1016&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;없다&amp;rdquo;라는 결과를 냈다면 그것도 정상적인 분석 결과다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1082&quot; data-start=&quot;1053&quot; data-ke-size=&quot;size16&quot;&gt;0건 발견과 분석 실패는 완전히 다른 상태다.&lt;/p&gt;
&lt;p data-end=&quot;1122&quot; data-start=&quot;1084&quot; data-ke-size=&quot;size16&quot;&gt;너무 당연한 이야기인데 만들 때는 그 차이를 제대로 생각하지 못했다.&lt;/p&gt;
&lt;hr data-end=&quot;1127&quot; data-start=&quot;1124&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1152&quot; data-start=&quot;1129&quot; data-ke-size=&quot;size26&quot;&gt;개발자인 내가 쓰면 이상하게 잘 된다&lt;/h2&gt;
&lt;p data-end=&quot;1172&quot; data-start=&quot;1154&quot; data-ke-size=&quot;size16&quot;&gt;이번에 가장 크게 느낀 부분이다.&lt;/p&gt;
&lt;p data-end=&quot;1205&quot; data-start=&quot;1174&quot; data-ke-size=&quot;size16&quot;&gt;개발자인 내가 내 서비스를 테스트하면 이상하게 잘 된다.&lt;/p&gt;
&lt;p data-end=&quot;1224&quot; data-start=&quot;1207&quot; data-ke-size=&quot;size16&quot;&gt;왜 그런지 생각해보면 간단하다.&lt;/p&gt;
&lt;p data-end=&quot;1255&quot; data-start=&quot;1226&quot; data-ke-size=&quot;size16&quot;&gt;나는 이미 이 서비스가 어떻게 동작하는지 알고 있다.&lt;/p&gt;
&lt;p data-end=&quot;1276&quot; data-start=&quot;1257&quot; data-ke-size=&quot;size16&quot;&gt;어떤 파일을 넣어야 하는지도 알고,&lt;/p&gt;
&lt;p data-end=&quot;1297&quot; data-start=&quot;1278&quot; data-ke-size=&quot;size16&quot;&gt;어떤 버튼을 눌러야 하는지도 알고,&lt;/p&gt;
&lt;p data-end=&quot;1319&quot; data-start=&quot;1299&quot; data-ke-size=&quot;size16&quot;&gt;어떤 순서로 사용해야 하는지도 안다.&lt;/p&gt;
&lt;p data-end=&quot;1349&quot; data-start=&quot;1321&quot; data-ke-size=&quot;size16&quot;&gt;심지어 어떤 결과가 나와야 정상인지까지 알고 있다.&lt;/p&gt;
&lt;p data-end=&quot;1380&quot; data-start=&quot;1351&quot; data-ke-size=&quot;size16&quot;&gt;그러니까 나도 모르게 &lt;b&gt;정답을 알고 테스트한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1404&quot; data-start=&quot;1382&quot; data-ke-size=&quot;size16&quot;&gt;사용자가 틀릴 수 있는 길을 피해 간다.&lt;/p&gt;
&lt;p data-end=&quot;1437&quot; data-start=&quot;1406&quot; data-ke-size=&quot;size16&quot;&gt;개발자인 내가 원하는 방향으로 서비스가 흘러가게 만든다.&lt;/p&gt;
&lt;p data-end=&quot;1452&quot; data-start=&quot;1439&quot; data-ke-size=&quot;size16&quot;&gt;그러니 당연히 잘 된다.&lt;/p&gt;
&lt;hr data-end=&quot;1457&quot; data-start=&quot;1454&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1488&quot; data-start=&quot;1459&quot; data-ke-size=&quot;size26&quot;&gt;실제 사용자는 내가 생각한 대로 움직이지 않는다&lt;/h2&gt;
&lt;p data-end=&quot;1499&quot; data-start=&quot;1490&quot; data-ke-size=&quot;size16&quot;&gt;사용자는 다르다.&lt;/p&gt;
&lt;p data-end=&quot;1511&quot; data-start=&quot;1501&quot; data-ke-size=&quot;size16&quot;&gt;처음 보는 화면에서&lt;/p&gt;
&lt;p data-end=&quot;1537&quot; data-start=&quot;1513&quot; data-ke-size=&quot;size16&quot;&gt;내가 예상하지 못한 파일을 올릴 수도 있고,&lt;/p&gt;
&lt;p data-end=&quot;1572&quot; data-start=&quot;1539&quot; data-ke-size=&quot;size16&quot;&gt;내가 중요하다고 생각하지 않은 버튼을 먼저 누를 수도 있고,&lt;/p&gt;
&lt;p data-end=&quot;1602&quot; data-start=&quot;1574&quot; data-ke-size=&quot;size16&quot;&gt;아예 내가 생각하지 못한 순서로 사용할 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;1621&quot; data-start=&quot;1604&quot; data-ke-size=&quot;size16&quot;&gt;그리고 그게 이상한 게 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1635&quot; data-start=&quot;1623&quot; data-ke-size=&quot;size16&quot;&gt;오히려 그게 정상이다.&lt;/p&gt;
&lt;p data-end=&quot;1665&quot; data-start=&quot;1637&quot; data-ke-size=&quot;size16&quot;&gt;서비스가 사용자의 행동을 통제해야 하는 게 아니라,&lt;/p&gt;
&lt;p data-end=&quot;1708&quot; data-start=&quot;1667&quot; data-ke-size=&quot;size16&quot;&gt;어느 정도는 &lt;b&gt;사용자가 예상하지 못한 방식으로 사용해도 버텨야 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1736&quot; data-start=&quot;1710&quot; data-ke-size=&quot;size16&quot;&gt;이번에 발견한 문제도 결국 그 차이에서 나왔다.&lt;/p&gt;
&lt;p data-end=&quot;1763&quot; data-start=&quot;1738&quot; data-ke-size=&quot;size16&quot;&gt;나는 계속 내가 만든 기능을 확인하고 있었고,&lt;/p&gt;
&lt;p data-end=&quot;1792&quot; data-start=&quot;1765&quot; data-ke-size=&quot;size16&quot;&gt;실제 사용 상황을 충분히 확인하지 못하고 있었다.&lt;/p&gt;
&lt;hr data-end=&quot;1797&quot; data-start=&quot;1794&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1820&quot; data-start=&quot;1799&quot; data-ke-size=&quot;size26&quot;&gt;배포하고 나서야 테스트가 달라졌다&lt;/h2&gt;
&lt;p data-end=&quot;1856&quot; data-start=&quot;1822&quot; data-ke-size=&quot;size16&quot;&gt;배포 전에는 테스트라는 게 거의 내 컴퓨터 안에서 이루어졌다.&lt;/p&gt;
&lt;p data-end=&quot;1867&quot; data-start=&quot;1858&quot; data-ke-size=&quot;size16&quot;&gt;코드를 수정하고,&lt;/p&gt;
&lt;p data-end=&quot;1878&quot; data-start=&quot;1869&quot; data-ke-size=&quot;size16&quot;&gt;서버를 실행하고,&lt;/p&gt;
&lt;p data-end=&quot;1892&quot; data-start=&quot;1880&quot; data-ke-size=&quot;size16&quot;&gt;브라우저에서 확인하고,&lt;/p&gt;
&lt;p data-end=&quot;1906&quot; data-start=&quot;1894&quot; data-ke-size=&quot;size16&quot;&gt;다시 코드를 수정했다.&lt;/p&gt;
&lt;p data-end=&quot;1931&quot; data-start=&quot;1908&quot; data-ke-size=&quot;size16&quot;&gt;그런데 배포를 하고 나니까 조금 달라졌다.&lt;/p&gt;
&lt;p data-end=&quot;1952&quot; data-start=&quot;1933&quot; data-ke-size=&quot;size16&quot;&gt;PC가 아닌 휴대폰에서도 열어보고,&lt;/p&gt;
&lt;p data-end=&quot;1970&quot; data-start=&quot;1954&quot; data-ke-size=&quot;size16&quot;&gt;그냥 평범한 사진도 넣어보고,&lt;/p&gt;
&lt;p data-end=&quot;2006&quot; data-start=&quot;1972&quot; data-ke-size=&quot;size16&quot;&gt;내가 개발할 때 사용하지 않던 방식으로 화면을 눌러보게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;2038&quot; data-start=&quot;2008&quot; data-ke-size=&quot;size16&quot;&gt;무엇보다 이제는 다른 사람에게 URL을 보낼 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2051&quot; data-start=&quot;2040&quot; data-ke-size=&quot;size16&quot;&gt;그 순간부터 테스트가&lt;/p&gt;
&lt;p data-end=&quot;2081&quot; data-start=&quot;2053&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;내가 만든 기능이 동작하는지 확인하는 것&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2085&quot; data-start=&quot;2083&quot; data-ke-size=&quot;size16&quot;&gt;에서&lt;/p&gt;
&lt;p data-end=&quot;2116&quot; data-start=&quot;2087&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;다른 사람이 사용해도 괜찮은지 확인하는 것&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2132&quot; data-start=&quot;2118&quot; data-ke-size=&quot;size16&quot;&gt;으로 조금 바뀐 것 같다.&lt;/p&gt;
&lt;hr data-end=&quot;2137&quot; data-start=&quot;2134&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2167&quot; data-start=&quot;2139&quot; data-ke-size=&quot;size26&quot;&gt;버그 하나를 고쳤는데 생각은 꽤 많이 바뀌었다&lt;/h2&gt;
&lt;p data-end=&quot;2193&quot; data-start=&quot;2169&quot; data-ke-size=&quot;size16&quot;&gt;이번에 발견한 건 사실 큰 버그는 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;2231&quot; data-start=&quot;2195&quot; data-ke-size=&quot;size16&quot;&gt;몇 군데 흐름을 다시 확인하고 수정하면 해결할 수 있는 문제였다.&lt;/p&gt;
&lt;p data-end=&quot;2267&quot; data-start=&quot;2233&quot; data-ke-size=&quot;size16&quot;&gt;그런데 버그를 고치는 것보다 더 기억에 남은 건 따로 있었다.&lt;/p&gt;
&lt;p data-end=&quot;2295&quot; data-start=&quot;2269&quot; data-ke-size=&quot;size16&quot;&gt;나는 그동안 테스트를 꽤 많이 했다고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;2312&quot; data-start=&quot;2297&quot; data-ke-size=&quot;size16&quot;&gt;그런데 내가 했던 건 대부분&lt;/p&gt;
&lt;p data-end=&quot;2355&quot; data-start=&quot;2314&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 만든 기능이 내가 생각한 대로 움직이는지 확인하는 테스트&lt;/b&gt;였다.&lt;/p&gt;
&lt;p data-end=&quot;2386&quot; data-start=&quot;2357&quot; data-ke-size=&quot;size16&quot;&gt;사용자 입장에서 서비스를 보는 건 또 다른 문제였다.&lt;/p&gt;
&lt;p data-end=&quot;2396&quot; data-start=&quot;2388&quot; data-ke-size=&quot;size16&quot;&gt;개발하면서 자꾸&lt;/p&gt;
&lt;blockquote data-end=&quot;2410&quot; data-start=&quot;2398&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2410&quot; data-start=&quot;2400&quot; data-ke-size=&quot;size16&quot;&gt;왜 이걸 못 봤지?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2425&quot; data-start=&quot;2412&quot; data-ke-size=&quot;size16&quot;&gt;라는 생각을 하게 된다.&lt;/p&gt;
&lt;p data-end=&quot;2446&quot; data-start=&quot;2427&quot; data-ke-size=&quot;size16&quot;&gt;아마 앞으로도 계속 그럴 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;2470&quot; data-start=&quot;2448&quot; data-ke-size=&quot;size16&quot;&gt;그래도 이번에는 이유를 하나 알게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;2509&quot; data-start=&quot;2472&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 너무 잘 알고 있기 때문에 오히려 못 보는 것도 있다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;2514&quot; data-start=&quot;2511&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2538&quot; data-start=&quot;2516&quot; data-ke-size=&quot;size26&quot;&gt;이제 다른 사람에게 맡겨보려고 한다&lt;/h2&gt;
&lt;p data-end=&quot;2565&quot; data-start=&quot;2540&quot; data-ke-size=&quot;size16&quot;&gt;지금까지는 거의 내가 만들고 내가 테스트했다.&lt;/p&gt;
&lt;p data-end=&quot;2595&quot; data-start=&quot;2567&quot; data-ke-size=&quot;size16&quot;&gt;이제는 처음 보는 사람에게 URL만 보내보고 싶다.&lt;/p&gt;
&lt;p data-end=&quot;2626&quot; data-start=&quot;2597&quot; data-ke-size=&quot;size16&quot;&gt;별다른 설명 없이 한 번 사용해보라고 해볼 생각이다.&lt;/p&gt;
&lt;p data-end=&quot;2638&quot; data-start=&quot;2628&quot; data-ke-size=&quot;size16&quot;&gt;어디에서 멈추는지,&lt;/p&gt;
&lt;p data-end=&quot;2655&quot; data-start=&quot;2640&quot; data-ke-size=&quot;size16&quot;&gt;무슨 버튼을 먼저 누르는지,&lt;/p&gt;
&lt;p data-end=&quot;2686&quot; data-start=&quot;2657&quot; data-ke-size=&quot;size16&quot;&gt;내가 당연하다고 생각했던 부분에서 헷갈리지는 않는지.&lt;/p&gt;
&lt;p data-end=&quot;2712&quot; data-start=&quot;2688&quot; data-ke-size=&quot;size16&quot;&gt;그걸 보면 또 새로운 문제가 보일 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;2726&quot; data-start=&quot;2714&quot; data-ke-size=&quot;size16&quot;&gt;조금 무섭기도 하지만,&lt;/p&gt;
&lt;p data-end=&quot;2750&quot; data-start=&quot;2728&quot; data-ke-size=&quot;size16&quot;&gt;이제는 그게 더 필요한 단계인 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;2750&quot; data-start=&quot;2728&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;2800&quot; data-start=&quot;2752&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개발자인 내가 찾는 버그보다&lt;br /&gt;사용자가 찾는 버그가 더 중요할 수도 있으니까.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; data-start=&quot;2511&quot; data-end=&quot;2514&quot; /&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;2800&quot; data-start=&quot;2752&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;직접 만든 서비스를 다른 사람에게 처음 테스트시켜봤을 때, 예상하지 못한 곳에서 막혔던 경험이 있다면 궁금하다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/20</guid>
      <comments>https://nocklock.tistory.com/20#entry20comment</comments>
      <pubDate>Fri, 25 Sep 2026 08:19:27 +0900</pubDate>
    </item>
    <item>
      <title>Spring Boot 8080 포트 충돌 해결 &amp;mdash; Port 8080 was already in use 오류</title>
      <link>https://nocklock.tistory.com/30</link>
      <description>&lt;p data-end=&quot;177&quot; data-start=&quot;136&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot 프로젝트를 다시 실행하려는데 서버가 올라오지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;209&quot; data-start=&quot;179&quot; data-ke-size=&quot;size16&quot;&gt;코드를 잘못 건드린 줄 알았는데 원인은 훨씬 단순했다.&lt;/p&gt;
&lt;p data-end=&quot;245&quot; data-start=&quot;211&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;8080 포트를 이미 다른 프로세스가 사용하고 있었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;311&quot; data-start=&quot;247&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot를 사용하다 보면 한 번쯤 보게 되는 문제인데, 막상 개발 흐름 중간에 만나면 생각보다 귀찮다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 21일 오후 12_01_34.png&quot; data-origin-width=&quot;1225&quot; data-origin-height=&quot;1284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bphAjC/dJMcaidXD9C/ZYkXfafkqyJQeculTw0851/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bphAjC/dJMcaidXD9C/ZYkXfafkqyJQeculTw0851/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bphAjC/dJMcaidXD9C/ZYkXfafkqyJQeculTw0851/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbphAjC%2FdJMcaidXD9C%2FZYkXfafkqyJQeculTw0851%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; alt=&quot;portChange&quot; loading=&quot;lazy&quot; width=&quot;1225&quot; height=&quot;1284&quot; data-filename=&quot;ChatGPT Image 2026년 9월 21일 오후 12_01_34.png&quot; data-origin-width=&quot;1225&quot; data-origin-height=&quot;1284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;311&quot; data-start=&quot;247&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-end=&quot;316&quot; data-start=&quot;313&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;349&quot; data-start=&quot;318&quot; data-section-id=&quot;1h8fmkb&quot; data-ke-size=&quot;size26&quot;&gt;Port 8080 was already in use&lt;/h2&gt;
&lt;p data-end=&quot;399&quot; data-start=&quot;351&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot는 별도로 설정하지 않으면 기본적으로 8080 포트를 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;475&quot; data-start=&quot;401&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이미 다른 프로그램이나 이전에 실행한 서버가 8080 포트를 잡고 있으면 새로운 Spring Boot 서버를 실행할 수 없다.&lt;/p&gt;
&lt;p data-end=&quot;499&quot; data-start=&quot;477&quot; data-ke-size=&quot;size16&quot;&gt;보통 이런 형태의 메시지를 만나게 된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Web server failed to start.
Port 8080 was already in use.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;614&quot; data-start=&quot;572&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 애플리케이션 오류인가 싶었지만, 메시지를 보면 원인은 꽤 명확하다.&lt;/p&gt;
&lt;p data-end=&quot;659&quot; data-start=&quot;616&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Spring Boot가 사용할 8080 포트가 비어 있지 않은 것이다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;664&quot; data-start=&quot;661&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;680&quot; data-start=&quot;666&quot; data-section-id=&quot;uovw2k&quot; data-ke-size=&quot;size26&quot;&gt;왜 이런 일이 생길까&lt;/h2&gt;
&lt;p data-end=&quot;720&quot; data-start=&quot;682&quot; data-ke-size=&quot;size16&quot;&gt;내 경우에는 개발하면서 여러 서버와 도구를 반복해서 실행하고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;802&quot; data-start=&quot;722&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot도 여러 번 실행하고 있었고, 개발 환경을 이것저것 바꾸면서 테스트하다 보니 8080 포트가 이미 사용 중인 상황이 생겼다.&lt;/p&gt;
&lt;p data-end=&quot;826&quot; data-start=&quot;804&quot; data-ke-size=&quot;size16&quot;&gt;이런 문제는 보통 다음 경우에 발생한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;950&quot; data-start=&quot;828&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;864&quot; data-start=&quot;828&quot; data-section-id=&quot;12894j1&quot;&gt;이전에 실행한 Spring Boot가 아직 종료되지 않은 경우&lt;/li&gt;
&lt;li data-end=&quot;896&quot; data-start=&quot;865&quot; data-section-id=&quot;18z79tc&quot;&gt;다른 Java 애플리케이션이 8080을 사용하는 경우&lt;/li&gt;
&lt;li data-end=&quot;924&quot; data-start=&quot;897&quot; data-section-id=&quot;7zkn8c&quot;&gt;Tomcat 같은 다른 서버가 실행 중인 경우&lt;/li&gt;
&lt;li data-end=&quot;950&quot; data-start=&quot;925&quot; data-section-id=&quot;dz8roc&quot;&gt;IDE에서 애플리케이션을 중복 실행한 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;966&quot; data-start=&quot;952&quot; data-ke-size=&quot;size16&quot;&gt;결국 선택지는 두 가지다.&lt;/p&gt;
&lt;p data-end=&quot;1021&quot; data-start=&quot;968&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;8080을 사용하는 프로세스를 종료하거나, Spring Boot의 포트를 변경하면 된다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1026&quot; data-start=&quot;1023&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1044&quot; data-start=&quot;1028&quot; data-section-id=&quot;8hi77p&quot; data-ke-size=&quot;size26&quot;&gt;나는 8081로 변경했다&lt;/h2&gt;
&lt;p data-end=&quot;1082&quot; data-start=&quot;1046&quot; data-ke-size=&quot;size16&quot;&gt;이번 프로젝트에서는 반드시 8080을 사용해야 할 이유가 없었다.&lt;/p&gt;
&lt;p data-end=&quot;1155&quot; data-start=&quot;1084&quot; data-ke-size=&quot;size16&quot;&gt;그래서 포트를 차지하고 있는 프로세스를 추적하는 데 시간을 쓰기보다 Spring Boot의 실행 포트를 8081로 변경했다.&lt;/p&gt;
&lt;p data-end=&quot;1204&quot; data-start=&quot;1157&quot; data-ke-size=&quot;size16&quot;&gt;application.properties를 사용한다면 다음 설정을 추가하면 된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;server.port=8081&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1280&quot; data-start=&quot;1242&quot; data-ke-size=&quot;size16&quot;&gt;application.yml을 사용한다면 이렇게 설정할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;server:
  port: 8081&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1331&quot; data-start=&quot;1316&quot; data-ke-size=&quot;size16&quot;&gt;다시 애플리케이션을 실행하고&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;http://localhost:8081&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1375&quot; data-start=&quot;1368&quot; data-ke-size=&quot;size16&quot;&gt;로 접근했다.&lt;/p&gt;
&lt;p data-end=&quot;1392&quot; data-start=&quot;1377&quot; data-ke-size=&quot;size16&quot;&gt;서버는 정상적으로 실행됐다.&lt;/p&gt;
&lt;p data-end=&quot;1411&quot; data-start=&quot;1394&quot; data-ke-size=&quot;size16&quot;&gt;문제 자체는 생각보다 간단했다.&lt;/p&gt;
&lt;hr data-end=&quot;1416&quot; data-start=&quot;1413&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1438&quot; data-start=&quot;1418&quot; data-section-id=&quot;1w8i8g9&quot; data-ke-size=&quot;size26&quot;&gt;8080을 계속 사용해야 한다면&lt;/h2&gt;
&lt;p data-end=&quot;1465&quot; data-start=&quot;1440&quot; data-ke-size=&quot;size16&quot;&gt;물론 항상 포트를 바꾸는 것이 정답은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1524&quot; data-start=&quot;1467&quot; data-ke-size=&quot;size16&quot;&gt;8080으로 고정해야 하는 환경이라면 &lt;b&gt;8080을 사용하는 프로세스를 찾아서 종료하는 편이 맞다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1557&quot; data-start=&quot;1526&quot; data-ke-size=&quot;size16&quot;&gt;Windows에서는 다음과 같이 포트를 확인할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;netstat -ano | findstr :8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1641&quot; data-start=&quot;1601&quot; data-ke-size=&quot;size16&quot;&gt;마지막에 표시되는 PID를 확인한 뒤 어떤 프로세스인지 찾아볼 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;tasklist | findstr PID번호&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1725&quot; data-start=&quot;1681&quot; data-ke-size=&quot;size16&quot;&gt;필요하다면 해당 프로세스를 종료하고 다시 Spring Boot를 실행하면 된다.&lt;/p&gt;
&lt;p data-end=&quot;1775&quot; data-start=&quot;1727&quot; data-ke-size=&quot;size16&quot;&gt;다만 무작정 프로세스를 종료하기보다는 &lt;b&gt;어떤 프로그램인지 먼저 확인하는 게 좋다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1780&quot; data-start=&quot;1777&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1801&quot; data-start=&quot;1782&quot; data-section-id=&quot;1rb3apx&quot; data-ke-size=&quot;size26&quot;&gt;생각보다 자주 만나는 문제였다&lt;/h2&gt;
&lt;p data-end=&quot;1830&quot; data-start=&quot;1803&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 해결하는 데 오래 걸린 문제는 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;1876&quot; data-start=&quot;1832&quot; data-ke-size=&quot;size16&quot;&gt;그런데 개발을 다시 하면서 느끼는 건 이런 작은 문제들이 계속 나온다는 것이다.&lt;/p&gt;
&lt;p data-end=&quot;1918&quot; data-start=&quot;1878&quot; data-ke-size=&quot;size16&quot;&gt;코드가 틀린 것도 아니고, Spring Boot가 고장 난 것도 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1975&quot; data-start=&quot;1920&quot; data-ke-size=&quot;size16&quot;&gt;그냥 &lt;b&gt;내가 실행하려는 서버가 사용할 자리를 다른 프로그램이 먼저 사용하고 있었던 것&lt;/b&gt;뿐이었다.&lt;/p&gt;
&lt;p data-end=&quot;2018&quot; data-start=&quot;1977&quot; data-ke-size=&quot;size16&quot;&gt;개발을 다시 시작하고 나서는 이런 작은 오류도 그냥 넘기지 않고 왜 생겼는지 한 번씩 확인하게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;2059&quot; data-start=&quot;2020&quot; data-ke-size=&quot;size16&quot;&gt;메시지를 읽고 원인을 하나씩 줄이다 보면 대부분 어디선가 답이 나온다.&lt;/p&gt;
&lt;p data-end=&quot;2101&quot; data-start=&quot;2061&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 원인이 8080이었고, 나는 8081로 한 칸 옮겼다.&lt;/p&gt;
&lt;hr data-end=&quot;2106&quot; data-start=&quot;2103&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2114&quot; data-start=&quot;2108&quot; data-section-id=&quot;1hrqjbz&quot; data-ke-size=&quot;size23&quot;&gt;정리&lt;/h3&gt;
&lt;p data-end=&quot;2170&quot; data-start=&quot;2116&quot; data-ke-size=&quot;size16&quot;&gt;Port 8080 was already in use가 나온다면 먼저 두 가지를 확인하면 된다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;2245&quot; data-start=&quot;2172&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;2201&quot; data-start=&quot;2172&quot; data-section-id=&quot;yw1qz3&quot;&gt;8080을 사용 중인 프로세스를 찾아 종료한다.&lt;/li&gt;
&lt;li data-end=&quot;2245&quot; data-start=&quot;2202&quot; data-section-id=&quot;tyebme&quot;&gt;8080을 꼭 사용할 필요가 없다면 server.port를 변경한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;2290&quot; data-start=&quot;2247&quot; data-ke-size=&quot;size16&quot;&gt;내 경우에는 두 번째 방법으로 해결했고, 이후 개발을 계속 진행할 수 있었다.&lt;/p&gt;
&lt;hr data-end=&quot;2295&quot; data-start=&quot;2292&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2311&quot; data-start=&quot;2297&quot; data-section-id=&quot;1j4qkxz&quot; data-ke-size=&quot;size26&quot;&gt;Nocklock 연결&lt;/h2&gt;
&lt;p data-end=&quot;2422&quot; data-start=&quot;2365&quot; data-ke-size=&quot;size16&quot;&gt;이 문제는 프로젝트를 실제 서비스 형태로 만들면서 겪은 여러 개발 환경 문제 중 하나였다.&lt;br /&gt;로컬에서는 잘 동작하던 프로젝트를 다른 환경에서도 실행할 수 있도록 만드는 과정은 따로 기록하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;2432&quot; data-start=&quot;2424&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2432&quot; data-start=&quot;2424&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;관련 글&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2607&quot; data-start=&quot;2434&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;125&quot; data-start=&quot;42&quot; data-section-id=&quot;1y3sbsk&quot;&gt;&lt;a href=&quot;https://nocklock.tistory.com/16&quot;&gt;내 컴퓨터에서는 잘 되는데, 다른 사람도 쓸 수 있어야 했다 | RE:개발자 #10&lt;/a&gt;&lt;/li&gt;
&lt;li data-end=&quot;213&quot; data-start=&quot;126&quot; data-section-id=&quot;i2nbhm&quot;&gt;&lt;a href=&quot;https://nocklock.tistory.com/18&quot; data-end=&quot;213&quot; data-start=&quot;128&quot;&gt;서버에 올리면 끝인 줄 알았다 &amp;mdash; Docker를 처음 제대로 써봤다 | RE:개발자 #11&lt;/a&gt;&lt;/li&gt;
&lt;li data-end=&quot;314&quot; data-start=&quot;214&quot; data-section-id=&quot;1e372sy&quot;&gt;&lt;a href=&quot;https://nocklock.tistory.com/24&quot; data-end=&quot;314&quot; data-start=&quot;216&quot;&gt;Spring Boot Docker 배포 방법 &amp;mdash; Windows/WSL부터 Railway까지 직접 해보며 막힌 것들&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2627&quot; data-start=&quot;2609&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발 노트</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/30</guid>
      <comments>https://nocklock.tistory.com/30#entry30comment</comments>
      <pubDate>Thu, 24 Sep 2026 20:30:23 +0900</pubDate>
    </item>
    <item>
      <title>localhost를 지웠더니 진짜 서비스가 됐다 | RE:개발자 #12</title>
      <link>https://nocklock.tistory.com/19</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오전 12_12_42.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Drwb7/dJMcaaGXu7V/IndzNKB9A4AOOeBt7kBLak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Drwb7/dJMcaaGXu7V/IndzNKB9A4AOOeBt7kBLak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Drwb7/dJMcaaGXu7V/IndzNKB9A4AOOeBt7kBLak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDrwb7%2FdJMcaaGXu7V%2FIndzNKB9A4AOOeBt7kBLak%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; alt=&quot;Deploy&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오전 12_12_42.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;181&quot; data-start=&quot;143&quot; data-ke-size=&quot;size16&quot;&gt;Docker까지 준비하고 나니 이제 정말 서버에 올리는 일만 남았다.&lt;/p&gt;
&lt;p data-end=&quot;203&quot; data-start=&quot;183&quot; data-ke-size=&quot;size16&quot;&gt;물론 여기까지 오면서 이미 몇 번이나&lt;/p&gt;
&lt;p data-end=&quot;227&quot; data-start=&quot;205&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;이제 거의 다 한 거 아닌가?&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;237&quot; data-start=&quot;229&quot; data-ke-size=&quot;size16&quot;&gt;라고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;257&quot; data-start=&quot;239&quot; data-ke-size=&quot;size16&quot;&gt;그리고 그 생각은 대체로 틀렸다.&lt;/p&gt;
&lt;p data-end=&quot;300&quot; data-start=&quot;259&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 Railway를 이용해서 프로젝트를 실제 서버에 올려보기로 했다.&lt;/p&gt;
&lt;hr data-end=&quot;305&quot; data-start=&quot;302&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;338&quot; data-start=&quot;307&quot; data-ke-size=&quot;size26&quot;&gt;GitHub에 올린 코드가 실제로 실행되기 시작했다&lt;/h2&gt;
&lt;p data-end=&quot;376&quot; data-start=&quot;340&quot; data-ke-size=&quot;size16&quot;&gt;지금까지 GitHub는 내게 주로 소스 코드를 저장하는 곳이었다.&lt;/p&gt;
&lt;p data-end=&quot;387&quot; data-start=&quot;378&quot; data-ke-size=&quot;size16&quot;&gt;코드를 수정하고,&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;git add .
git commit
git push&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;455&quot; data-start=&quot;432&quot; data-ke-size=&quot;size16&quot;&gt;하면 GitHub에 변경 내용이 올라간다.&lt;/p&gt;
&lt;p data-end=&quot;468&quot; data-start=&quot;457&quot; data-ke-size=&quot;size16&quot;&gt;여기까지는 익숙했다.&lt;/p&gt;
&lt;p data-end=&quot;499&quot; data-start=&quot;470&quot; data-ke-size=&quot;size16&quot;&gt;그런데 Railway와 연결하고 나니 조금 달라졌다.&lt;/p&gt;
&lt;p data-end=&quot;548&quot; data-start=&quot;501&quot; data-ke-size=&quot;size16&quot;&gt;내가 GitHub에 올린 코드를 가져가서 서버에서 빌드하고, 실제로 실행까지 해준다.&lt;/p&gt;
&lt;p data-end=&quot;568&quot; data-start=&quot;550&quot; data-ke-size=&quot;size16&quot;&gt;화면에는 하나씩 상태가 표시됐다.&lt;/p&gt;
&lt;p data-end=&quot;576&quot; data-start=&quot;570&quot; data-ke-size=&quot;size16&quot;&gt;Build.&lt;/p&gt;
&lt;p data-end=&quot;585&quot; data-start=&quot;578&quot; data-ke-size=&quot;size16&quot;&gt;Deploy.&lt;/p&gt;
&lt;p data-end=&quot;600&quot; data-start=&quot;587&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 그냥 기다렸다.&lt;/p&gt;
&lt;p data-end=&quot;635&quot; data-start=&quot;602&quot; data-ke-size=&quot;size16&quot;&gt;솔직히 이런 화면을 보고 있으면 할 수 있는 게 별로 없다.&lt;/p&gt;
&lt;p data-end=&quot;655&quot; data-start=&quot;637&quot; data-ke-size=&quot;size16&quot;&gt;성공하기를 기다리는 수밖에 없다.&lt;/p&gt;
&lt;p data-end=&quot;680&quot; data-start=&quot;657&quot; data-ke-size=&quot;size16&quot;&gt;그러다 하나씩 완료 표시가 붙기 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;698&quot; data-start=&quot;682&quot; data-ke-size=&quot;size16&quot;&gt;그리고 마지막 하나가 남았다.&lt;/p&gt;
&lt;p data-end=&quot;724&quot; data-start=&quot;700&quot; data-ke-size=&quot;size16&quot;&gt;그게 끝났을 때 화면을 보면서 잠깐 멈췄다.&lt;/p&gt;
&lt;p data-end=&quot;738&quot; data-start=&quot;726&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;진짜 된 건가?&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;743&quot; data-start=&quot;740&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;769&quot; data-start=&quot;745&quot; data-ke-size=&quot;size26&quot;&gt;localhost가 아닌 주소가 생겼다&lt;/h2&gt;
&lt;p data-end=&quot;796&quot; data-start=&quot;771&quot; data-ke-size=&quot;size16&quot;&gt;Railway에서 서비스 주소가 하나 생겼다.&lt;/p&gt;
&lt;p data-end=&quot;832&quot; data-start=&quot;798&quot; data-ke-size=&quot;size16&quot;&gt;지금까지 내 프로젝트에 접속하려면 항상 이런 주소를 사용했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;localhost:8081&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;902&quot; data-start=&quot;862&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터에서 Spring Boot를 실행해야만 접속할 수 있는 주소다.&lt;/p&gt;
&lt;p data-end=&quot;931&quot; data-start=&quot;904&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이번에는 처음 보는 인터넷 주소가 생겼다.&lt;/p&gt;
&lt;p data-end=&quot;952&quot; data-start=&quot;933&quot; data-ke-size=&quot;size16&quot;&gt;주소를 복사해서 브라우저에 넣었다.&lt;/p&gt;
&lt;p data-end=&quot;961&quot; data-start=&quot;954&quot; data-ke-size=&quot;size16&quot;&gt;화면이 떴다.&lt;/p&gt;
&lt;p data-end=&quot;981&quot; data-start=&quot;963&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 사실 별 감흥이 없었다.&lt;/p&gt;
&lt;p data-end=&quot;1007&quot; data-start=&quot;983&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터에서 수십 번 보던 화면이었으니까.&lt;/p&gt;
&lt;p data-end=&quot;1029&quot; data-start=&quot;1009&quot; data-ke-size=&quot;size16&quot;&gt;그래서 잠시 후 이런 생각이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;1060&quot; data-start=&quot;1031&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;잠깐, 지금 Spring Boot 안 켰는데?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1096&quot; data-start=&quot;1062&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터에서 서버를 실행하지 않아도 서비스가 열리고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1112&quot; data-start=&quot;1098&quot; data-ke-size=&quot;size16&quot;&gt;그제야 조금 실감이 났다.&lt;/p&gt;
&lt;hr data-end=&quot;1117&quot; data-start=&quot;1114&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1133&quot; data-start=&quot;1119&quot; data-ke-size=&quot;size26&quot;&gt;휴대폰으로 들어가봤다&lt;/h2&gt;
&lt;p data-end=&quot;1149&quot; data-start=&quot;1135&quot; data-ke-size=&quot;size16&quot;&gt;그래도 아직 의심스러웠다.&lt;/p&gt;
&lt;p data-end=&quot;1173&quot; data-start=&quot;1151&quot; data-ke-size=&quot;size16&quot;&gt;같은 컴퓨터에서 접속해서 그런가 싶었다.&lt;/p&gt;
&lt;p data-end=&quot;1195&quot; data-start=&quot;1175&quot; data-ke-size=&quot;size16&quot;&gt;그래서 휴대폰에서도 주소를 열어봤다.&lt;/p&gt;
&lt;p data-end=&quot;1200&quot; data-start=&quot;1197&quot; data-ke-size=&quot;size16&quot;&gt;떴다.&lt;/p&gt;
&lt;p data-end=&quot;1216&quot; data-start=&quot;1202&quot; data-ke-size=&quot;size16&quot;&gt;사진도 선택할 수 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1257&quot; data-start=&quot;1218&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터와 상관없는 기기에서도 내가 만든 서비스에 접속할 수 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1284&quot; data-start=&quot;1259&quot; data-ke-size=&quot;size16&quot;&gt;그리고 여기서 내가 했던 생각은 꽤 단순했다.&lt;/p&gt;
&lt;p data-end=&quot;1318&quot; data-start=&quot;1286&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그럼 이제 나 말고 다른 사람도 쓸 수 있는 건가?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1324&quot; data-start=&quot;1320&quot; data-ke-size=&quot;size16&quot;&gt;맞았다.&lt;/p&gt;
&lt;p data-end=&quot;1339&quot; data-start=&quot;1326&quot; data-ke-size=&quot;size16&quot;&gt;URL만 보내주면 된다.&lt;/p&gt;
&lt;p data-end=&quot;1355&quot; data-start=&quot;1341&quot; data-ke-size=&quot;size16&quot;&gt;친구에게도 보낼 수 있고,&lt;/p&gt;
&lt;p data-end=&quot;1382&quot; data-start=&quot;1357&quot; data-ke-size=&quot;size16&quot;&gt;아내에게도 보내서 한번 써보라고 할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1411&quot; data-start=&quot;1384&quot; data-ke-size=&quot;size16&quot;&gt;#10에서 처음 고민했던 문제가 드디어 해결됐다.&lt;/p&gt;
&lt;blockquote data-end=&quot;1448&quot; data-start=&quot;1413&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1448&quot; data-start=&quot;1415&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터에서는 잘 되는데&lt;br /&gt;다른 사람은 어떻게 쓰지?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1470&quot; data-start=&quot;1450&quot; data-ke-size=&quot;size16&quot;&gt;이제는 적어도 접속은 할 수 있었다.&lt;/p&gt;
&lt;hr data-end=&quot;1475&quot; data-start=&quot;1472&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1501&quot; data-start=&quot;1477&quot; data-ke-size=&quot;size26&quot;&gt;별거 아닌 주소 하나인데 느낌이 달랐다&lt;/h2&gt;
&lt;p data-end=&quot;1534&quot; data-start=&quot;1503&quot; data-ke-size=&quot;size16&quot;&gt;개발하다 보면 localhost 화면을 정말 많이 본다.&lt;/p&gt;
&lt;p data-end=&quot;1546&quot; data-start=&quot;1536&quot; data-ke-size=&quot;size16&quot;&gt;회사에서도 그렇고,&lt;/p&gt;
&lt;p data-end=&quot;1562&quot; data-start=&quot;1548&quot; data-ke-size=&quot;size16&quot;&gt;혼자 공부할 때도 그렇고,&lt;/p&gt;
&lt;p data-end=&quot;1601&quot; data-start=&quot;1564&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot를 실행하고 브라우저를 열어서 기능을 확인한다.&lt;/p&gt;
&lt;p data-end=&quot;1645&quot; data-start=&quot;1603&quot; data-ke-size=&quot;size16&quot;&gt;그래서 localhost에서 화면이 뜨는 건 이제 별로 특별한 일이 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1680&quot; data-start=&quot;1647&quot; data-ke-size=&quot;size16&quot;&gt;그런데 인터넷 주소 하나가 생긴 것뿐인데 느낌이 꽤 달랐다.&lt;/p&gt;
&lt;p data-end=&quot;1698&quot; data-start=&quot;1682&quot; data-ke-size=&quot;size16&quot;&gt;이제 내가 만든 걸 설명하면서&lt;/p&gt;
&lt;blockquote data-end=&quot;1718&quot; data-start=&quot;1700&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1718&quot; data-start=&quot;1702&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;내 컴퓨터에서는 잘 돼요.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1733&quot; data-start=&quot;1720&quot; data-ke-size=&quot;size16&quot;&gt;라고 말할 필요가 없다.&lt;/p&gt;
&lt;p data-end=&quot;1749&quot; data-start=&quot;1735&quot; data-ke-size=&quot;size16&quot;&gt;그냥 주소를 보내면 된다.&lt;/p&gt;
&lt;p data-end=&quot;1773&quot; data-start=&quot;1751&quot; data-ke-size=&quot;size16&quot;&gt;누군가 실제로 들어와서 눌러볼 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1789&quot; data-start=&quot;1775&quot; data-ke-size=&quot;size16&quot;&gt;아직 부족한 기능도 많고,&lt;/p&gt;
&lt;p data-end=&quot;1805&quot; data-start=&quot;1791&quot; data-ke-size=&quot;size16&quot;&gt;디자인도 더 손봐야 하고,&lt;/p&gt;
&lt;p data-end=&quot;1828&quot; data-start=&quot;1807&quot; data-ke-size=&quot;size16&quot;&gt;서비스라고 부르기에는 작은 프로젝트다.&lt;/p&gt;
&lt;p data-end=&quot;1876&quot; data-start=&quot;1830&quot; data-ke-size=&quot;size16&quot;&gt;그래도 이 순간부터는 적어도 &lt;b&gt;나 혼자만 볼 수 있는 프로그램은 아니게 됐다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1881&quot; data-start=&quot;1878&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1900&quot; data-start=&quot;1883&quot; data-ke-size=&quot;size26&quot;&gt;그런데 주소가 조금 길었다&lt;/h2&gt;
&lt;p data-end=&quot;1930&quot; data-start=&quot;1902&quot; data-ke-size=&quot;size16&quot;&gt;배포에 성공하고 나니까 사람 마음이 또 이상해졌다.&lt;/p&gt;
&lt;p data-end=&quot;1944&quot; data-start=&quot;1932&quot; data-ke-size=&quot;size16&quot;&gt;몇 시간 전까지만 해도&lt;/p&gt;
&lt;p data-end=&quot;1962&quot; data-start=&quot;1946&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;제발 실행만 돼라.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1973&quot; data-start=&quot;1964&quot; data-ke-size=&quot;size16&quot;&gt;라고 생각했는데,&lt;/p&gt;
&lt;p data-end=&quot;1999&quot; data-start=&quot;1975&quot; data-ke-size=&quot;size16&quot;&gt;막상 실행되고 나니까 주소가 눈에 들어왔다.&lt;/p&gt;
&lt;p data-end=&quot;2039&quot; data-start=&quot;2001&quot; data-ke-size=&quot;size16&quot;&gt;Railway에서 만들어준 주소는 서비스 이름이 들어간 긴 주소였다.&lt;/p&gt;
&lt;p data-end=&quot;2044&quot; data-start=&quot;2041&quot; data-ke-size=&quot;size16&quot;&gt;갑자기&lt;/p&gt;
&lt;blockquote data-end=&quot;2065&quot; data-start=&quot;2046&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2065&quot; data-start=&quot;2048&quot; data-ke-size=&quot;size16&quot;&gt;이거 좀 더 예쁘게 못 바꾸나?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2078&quot; data-start=&quot;2067&quot; data-ke-size=&quot;size16&quot;&gt;라는 생각이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;2115&quot; data-start=&quot;2080&quot; data-ke-size=&quot;size16&quot;&gt;알아보니 내가 원하는 주소를 사용하려면 결국 도메인이 필요했다.&lt;/p&gt;
&lt;p data-end=&quot;2122&quot; data-start=&quot;2117&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;security.nocklock.com&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2166&quot; data-start=&quot;2159&quot; data-ke-size=&quot;size16&quot;&gt;같은 주소다.&lt;/p&gt;
&lt;p data-end=&quot;2194&quot; data-start=&quot;2168&quot; data-ke-size=&quot;size16&quot;&gt;그런데 나는 아직 도메인을 가지고 있지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;2207&quot; data-start=&quot;2196&quot; data-ke-size=&quot;size16&quot;&gt;그래서 일단 멈췄다.&lt;/p&gt;
&lt;p data-end=&quot;2265&quot; data-start=&quot;2209&quot; data-ke-size=&quot;size16&quot;&gt;지금 중요한 건 주소를 예쁘게 만드는 게 아니라 &lt;b&gt;서비스가 실제로 동작하는지 확인하는 것&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p data-end=&quot;2291&quot; data-start=&quot;2267&quot; data-ke-size=&quot;size16&quot;&gt;이런 것도 개발하면서 계속 배우는 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;2323&quot; data-start=&quot;2293&quot; data-ke-size=&quot;size16&quot;&gt;뭔가 하나 해결하면 바로 다음에 하고 싶은 게 생긴다.&lt;/p&gt;
&lt;p data-end=&quot;2350&quot; data-start=&quot;2325&quot; data-ke-size=&quot;size16&quot;&gt;그런데 전부 한 번에 하려고 하면 끝이 없다.&lt;/p&gt;
&lt;hr data-end=&quot;2355&quot; data-start=&quot;2352&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2381&quot; data-start=&quot;2357&quot; data-ke-size=&quot;size26&quot;&gt;이제 진짜 테스트를 받을 수 있게 됐다&lt;/h2&gt;
&lt;p data-end=&quot;2409&quot; data-start=&quot;2383&quot; data-ke-size=&quot;size16&quot;&gt;여기까지 개발하면서 테스트는 대부분 내가 했다.&lt;/p&gt;
&lt;p data-end=&quot;2440&quot; data-start=&quot;2411&quot; data-ke-size=&quot;size16&quot;&gt;당연히 내가 만든 기능이니까 사용 방법도 알고 있다.&lt;/p&gt;
&lt;p data-end=&quot;2462&quot; data-start=&quot;2442&quot; data-ke-size=&quot;size16&quot;&gt;어떤 이미지를 넣어야 하는지도 알고,&lt;/p&gt;
&lt;p data-end=&quot;2480&quot; data-start=&quot;2464&quot; data-ke-size=&quot;size16&quot;&gt;어디를 눌러야 하는지도 알고,&lt;/p&gt;
&lt;p data-end=&quot;2510&quot; data-start=&quot;2482&quot; data-ke-size=&quot;size16&quot;&gt;결과가 어떻게 나와야 하는지도 어느 정도 예상한다.&lt;/p&gt;
&lt;p data-end=&quot;2559&quot; data-start=&quot;2512&quot; data-ke-size=&quot;size16&quot;&gt;문제는 그래서 내가 테스트하면 &lt;b&gt;내가 생각한 방식으로만 사용하게 된다는 것&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;2583&quot; data-start=&quot;2561&quot; data-ke-size=&quot;size16&quot;&gt;이제 URL이 생겼으니 상황이 달라졌다.&lt;/p&gt;
&lt;p data-end=&quot;2613&quot; data-start=&quot;2585&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트를 처음 보는 사람에게 주소 하나만 보내고,&lt;/p&gt;
&lt;p data-end=&quot;2640&quot; data-start=&quot;2615&quot; data-ke-size=&quot;size16&quot;&gt;별다른 설명 없이 한번 써보라고 할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2673&quot; data-start=&quot;2642&quot; data-ke-size=&quot;size16&quot;&gt;그리고 실제로 서비스를 다시 사용하다가 하나를 발견했다.&lt;/p&gt;
&lt;p data-end=&quot;2722&quot; data-start=&quot;2675&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개인정보가 없는 사진에서는 이미지 보호하기 기능이 제대로 동작하지 않았다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2752&quot; data-start=&quot;2724&quot; data-ke-size=&quot;size16&quot;&gt;개발하면서 여러 번 테스트했는데도 못 본 문제였다.&lt;/p&gt;
&lt;p data-end=&quot;2777&quot; data-start=&quot;2754&quot; data-ke-size=&quot;size16&quot;&gt;배포에 성공하자마자 버그를 발견한 셈이다.&lt;/p&gt;
&lt;p data-end=&quot;2792&quot; data-start=&quot;2779&quot; data-ke-size=&quot;size16&quot;&gt;조금 허무하기도 했는데,&lt;/p&gt;
&lt;p data-end=&quot;2821&quot; data-start=&quot;2794&quot; data-ke-size=&quot;size16&quot;&gt;오히려 이때부터 진짜 테스트가 시작된 것 같았다.&lt;/p&gt;
&lt;p data-end=&quot;2851&quot; data-start=&quot;2823&quot; data-ke-size=&quot;size16&quot;&gt;localhost 밖으로 나오는 것까지는 성공했다.&lt;/p&gt;
&lt;p data-end=&quot;2857&quot; data-start=&quot;2853&quot; data-ke-size=&quot;size16&quot;&gt;그다음은&lt;/p&gt;
&lt;p data-end=&quot;2898&quot; data-start=&quot;2859&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 아닌 사람이 사용해도 괜찮은 서비스인지 확인하는 일이었다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/19</guid>
      <comments>https://nocklock.tistory.com/19#entry19comment</comments>
      <pubDate>Thu, 24 Sep 2026 08:12:59 +0900</pubDate>
    </item>
    <item>
      <title>ChatGPT 어디까지 써봤니? 문서&amp;middot;지도&amp;middot;판례로 현실 문제를 해결해본 과정</title>
      <link>https://nocklock.tistory.com/27</link>
      <description>&lt;p data-end=&quot;204&quot; data-start=&quot;184&quot; data-ke-size=&quot;size16&quot;&gt;ChatGPT를 꽤 오래 쓰고 있다.&lt;/p&gt;
&lt;p data-end=&quot;244&quot; data-start=&quot;206&quot; data-ke-size=&quot;size16&quot;&gt;코드를 물어보기도 하고, 글을 쓰기도 하고, 자료를 정리하기도 한다.&lt;/p&gt;
&lt;p data-end=&quot;270&quot; data-start=&quot;246&quot; data-ke-size=&quot;size16&quot;&gt;그런데 최근에는 조금 다른 방식으로 써봤다.&lt;/p&gt;
&lt;p data-end=&quot;308&quot; data-start=&quot;272&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;현실에서 생긴 문제 하나를 처음부터 끝까지 같이 풀어봤다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;322&quot; data-start=&quot;310&quot; data-ke-size=&quot;size16&quot;&gt;개발 문제가 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;384&quot; data-start=&quot;324&quot; data-ke-size=&quot;size16&quot;&gt;오래된 부동산 권리와 관련된 일이었고, 공공기관과 계약, 보상, 법률적인 내용까지 여러 가지가 섞여 있었다.&lt;/p&gt;
&lt;p data-end=&quot;416&quot; data-start=&quot;386&quot; data-ke-size=&quot;size16&quot;&gt;처음 연락을 받았을 때 가장 먼저 든 생각은 단순했다.&lt;/p&gt;
&lt;blockquote data-end=&quot;435&quot; data-start=&quot;418&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;435&quot; data-start=&quot;420&quot; data-ke-size=&quot;size16&quot;&gt;이걸 내가 어떻게 알아보지?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;491&quot; data-start=&quot;437&quot; data-ke-size=&quot;size16&quot;&gt;전문가에게 맡기면 편하겠지만, 문제는 내가 지금 상황조차 제대로 이해하지 못하고 있다는 것이었다.&lt;/p&gt;
&lt;p data-end=&quot;530&quot; data-start=&quot;493&quot; data-ke-size=&quot;size16&quot;&gt;무엇이 맞는지 모르는데 누군가에게 전부 맡기는 것도 조금 불편했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오후 05_35_43.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1536&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjfjBe/dJMcag73rN0/kI6uO68Y1wkGrIsYh2q7w1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjfjBe/dJMcag73rN0/kI6uO68Y1wkGrIsYh2q7w1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjfjBe/dJMcag73rN0/kI6uO68Y1wkGrIsYh2q7w1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjfjBe%2FdJMcag73rN0%2FkI6uO68Y1wkGrIsYh2q7w1%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; alt=&quot;어디까지 써봤니&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1536&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오후 05_35_43.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1536&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;551&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;그래서 일단 ChatGPT를 켰다.&lt;/p&gt;
&lt;hr data-end=&quot;556&quot; data-start=&quot;553&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;577&quot; data-start=&quot;558&quot; data-ke-size=&quot;size26&quot;&gt;처음에는 그냥 문서를 보여줬다&lt;/h2&gt;
&lt;p data-end=&quot;596&quot; data-start=&quot;579&quot; data-ke-size=&quot;size16&quot;&gt;가지고 있던 문서를 업로드했다.&lt;/p&gt;
&lt;p data-end=&quot;606&quot; data-start=&quot;598&quot; data-ke-size=&quot;size16&quot;&gt;그리고 물었다.&lt;/p&gt;
&lt;p data-end=&quot;631&quot; data-start=&quot;608&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;여기서 내가 봐야 할 게 뭐야?&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;679&quot; data-start=&quot;633&quot; data-ke-size=&quot;size16&quot;&gt;AI는 문서 안에서 권리관계, 면적, 과거 계약 내용 같은 것들을 하나씩 찾아냈다.&lt;/p&gt;
&lt;p data-end=&quot;695&quot; data-start=&quot;681&quot; data-ke-size=&quot;size16&quot;&gt;여기까지만 보면 평범하다.&lt;/p&gt;
&lt;p data-end=&quot;724&quot; data-start=&quot;697&quot; data-ke-size=&quot;size16&quot;&gt;PDF 읽어주는 건 이제 별로 신기하지 않으니까.&lt;/p&gt;
&lt;p data-end=&quot;744&quot; data-start=&quot;726&quot; data-ke-size=&quot;size16&quot;&gt;그런데 그다음부터 조금 달라졌다.&lt;/p&gt;
&lt;p data-end=&quot;803&quot; data-start=&quot;746&quot; data-ke-size=&quot;size16&quot;&gt;문서 안에 적혀 있는 정보를 기준으로 실제 판례를 찾아보고, 비슷한 사건이 있었는지 확인하기 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;842&quot; data-start=&quot;805&quot; data-ke-size=&quot;size16&quot;&gt;그 과정에서 지금 문제가 단순히 &amp;ldquo;예전에 돈을 받았느냐&amp;rdquo;가 아니라,&lt;/p&gt;
&lt;p data-end=&quot;884&quot; data-start=&quot;844&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;과거 계약으로 확보된 범위와 현재 법적으로 제한되는 범위가 같은가&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;903&quot; data-start=&quot;886&quot; data-ke-size=&quot;size16&quot;&gt;라는 문제라는 것을 알게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;955&quot; data-start=&quot;905&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 질문 자체를 어떻게 해야 할지도 몰랐는데, 문제의 형태가 조금씩 보이기 시작했다.&lt;/p&gt;
&lt;hr data-end=&quot;960&quot; data-start=&quot;957&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;980&quot; data-start=&quot;962&quot; data-ke-size=&quot;size26&quot;&gt;문서 다음에는 지도를 열었다&lt;/h2&gt;
&lt;p data-end=&quot;996&quot; data-start=&quot;982&quot; data-ke-size=&quot;size16&quot;&gt;여기서 끝낼 수도 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1034&quot; data-start=&quot;998&quot; data-ke-size=&quot;size16&quot;&gt;그런데 실제로 해당 시설이 토지를 어떻게 지나가는지가 궁금해졌다.&lt;/p&gt;
&lt;p data-end=&quot;1060&quot; data-start=&quot;1036&quot; data-ke-size=&quot;size16&quot;&gt;공공 지도 서비스를 열고 항공사진을 띄웠다.&lt;/p&gt;
&lt;p data-end=&quot;1095&quot; data-start=&quot;1062&quot; data-ke-size=&quot;size16&quot;&gt;필지 경계를 표시하고, 시설물을 찾아보고, 주변을 확대했다.&lt;/p&gt;
&lt;p data-end=&quot;1115&quot; data-start=&quot;1097&quot; data-ke-size=&quot;size16&quot;&gt;철탑처럼 보이는 구조물이 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1134&quot; data-start=&quot;1117&quot; data-ke-size=&quot;size16&quot;&gt;송전선으로 보이는 선도 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1157&quot; data-start=&quot;1136&quot; data-ke-size=&quot;size16&quot;&gt;ChatGPT에 화면을 계속 보여줬다.&lt;/p&gt;
&lt;p data-end=&quot;1167&quot; data-start=&quot;1159&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이게 맞아?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;1180&quot; data-start=&quot;1169&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;어디를 재야 해?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;1198&quot; data-start=&quot;1182&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이 방향으로 따라가면 돼?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;1257&quot; data-start=&quot;1200&quot; data-ke-size=&quot;size16&quot;&gt;그러다 보니 어느 순간 내가 AI에게 질문하는 게 아니라 &lt;b&gt;같이 디버깅하고 있다는 느낌&lt;/b&gt;이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;1273&quot; data-start=&quot;1259&quot; data-ke-size=&quot;size16&quot;&gt;개발할 때와 꽤 비슷했다.&lt;/p&gt;
&lt;p data-end=&quot;1286&quot; data-start=&quot;1275&quot; data-ke-size=&quot;size16&quot;&gt;가설을 하나 세운다.&lt;/p&gt;
&lt;p data-end=&quot;1297&quot; data-start=&quot;1288&quot; data-ke-size=&quot;size16&quot;&gt;자료를 확인한다.&lt;/p&gt;
&lt;p data-end=&quot;1311&quot; data-start=&quot;1299&quot; data-ke-size=&quot;size16&quot;&gt;틀리면 다시 수정한다.&lt;/p&gt;
&lt;p data-end=&quot;1328&quot; data-start=&quot;1313&quot; data-ke-size=&quot;size16&quot;&gt;그리고 다음 단서를 찾는다.&lt;/p&gt;
&lt;p data-end=&quot;1357&quot; data-start=&quot;1330&quot; data-ke-size=&quot;size16&quot;&gt;실제로 중간에 AI가 잘못 추정한 부분도 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1428&quot; data-start=&quot;1359&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 시설이 필지를 어느 방향으로 지나가는지 잘못 판단하기도 했고, 사진만 보고 특정 전압일 가능성을 높게 보기도 했다.&lt;/p&gt;
&lt;p data-end=&quot;1457&quot; data-start=&quot;1430&quot; data-ke-size=&quot;size16&quot;&gt;새로운 지도를 보여주자 그 추정은 다시 바뀌었다.&lt;/p&gt;
&lt;p data-end=&quot;1473&quot; data-start=&quot;1459&quot; data-ke-size=&quot;size16&quot;&gt;이 부분이 오히려 좋았다.&lt;/p&gt;
&lt;p data-end=&quot;1520&quot; data-start=&quot;1475&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AI의 첫 답을 정답으로 받아들이는 게 아니라 계속 검증하면서 쓰는 방식.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1547&quot; data-start=&quot;1522&quot; data-ke-size=&quot;size16&quot;&gt;내가 생각하는 AI 활용은 이쪽에 더 가깝다.&lt;/p&gt;
&lt;hr data-end=&quot;1552&quot; data-start=&quot;1549&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1573&quot; data-start=&quot;1554&quot; data-ke-size=&quot;size26&quot;&gt;결국 해야 할 일이 명확해졌다&lt;/h2&gt;
&lt;p data-end=&quot;1588&quot; data-start=&quot;1575&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 이런 상태였다.&lt;/p&gt;
&lt;blockquote data-end=&quot;1609&quot; data-start=&quot;1590&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1609&quot; data-start=&quot;1592&quot; data-ke-size=&quot;size16&quot;&gt;이게 무슨 문제인지도 모르겠다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1629&quot; data-start=&quot;1611&quot; data-ke-size=&quot;size16&quot;&gt;몇 시간 뒤에는 이렇게 바뀌었다.&lt;/p&gt;
&lt;blockquote data-end=&quot;1702&quot; data-start=&quot;1631&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1702&quot; data-start=&quot;1633&quot; data-ke-size=&quot;size16&quot;&gt;어떤 기관의 어느 담당 부서에 전화해야 하고,&lt;br /&gt;어떤 자료를 확인해야 하고,&lt;br /&gt;무엇을 질문해야 하는지 알고 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1730&quot; data-start=&quot;1704&quot; data-ke-size=&quot;size16&quot;&gt;실제로 전화할 때 사용할 질문도 전부 정리했다.&lt;/p&gt;
&lt;p data-end=&quot;1749&quot; data-start=&quot;1732&quot; data-ke-size=&quot;size16&quot;&gt;선로의 정확한 명칭은 무엇인지.&lt;/p&gt;
&lt;p data-end=&quot;1758&quot; data-start=&quot;1751&quot; data-ke-size=&quot;size16&quot;&gt;몇 kV인지.&lt;/p&gt;
&lt;p data-end=&quot;1784&quot; data-start=&quot;1760&quot; data-ke-size=&quot;size16&quot;&gt;과거 계약 면적은 어떤 기준으로 계산됐는지.&lt;/p&gt;
&lt;p data-end=&quot;1800&quot; data-start=&quot;1786&quot; data-ke-size=&quot;size16&quot;&gt;현재 추가 보상 대상인지.&lt;/p&gt;
&lt;p data-end=&quot;1816&quot; data-start=&quot;1802&quot; data-ke-size=&quot;size16&quot;&gt;추가되는 면적은 얼마인지.&lt;/p&gt;
&lt;p data-end=&quot;1842&quot; data-start=&quot;1818&quot; data-ke-size=&quot;size16&quot;&gt;과거 사용분에 대한 보상은 별개의 문제인지.&lt;/p&gt;
&lt;p data-end=&quot;1867&quot; data-start=&quot;1844&quot; data-ke-size=&quot;size16&quot;&gt;필요한 도면과 산출자료를 받을 수 있는지.&lt;/p&gt;
&lt;p data-end=&quot;1910&quot; data-start=&quot;1869&quot; data-ke-size=&quot;size16&quot;&gt;심지어 담당자가 나에게 반대로 질문할 가능성까지 생각해서 답변을 정리했다.&lt;/p&gt;
&lt;p data-end=&quot;1930&quot; data-start=&quot;1912&quot; data-ke-size=&quot;size16&quot;&gt;이쯤 되면 단순한 검색은 아니다.&lt;/p&gt;
&lt;hr data-end=&quot;1935&quot; data-start=&quot;1932&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1960&quot; data-start=&quot;1937&quot; data-ke-size=&quot;size26&quot;&gt;ChatGPT가 문제를 해결해줬을까?&lt;/h2&gt;
&lt;p data-end=&quot;1966&quot; data-start=&quot;1962&quot; data-ke-size=&quot;size16&quot;&gt;아니다.&lt;/p&gt;
&lt;p data-end=&quot;1989&quot; data-start=&quot;1968&quot; data-ke-size=&quot;size16&quot;&gt;이게 이번에 가장 크게 느낀 부분이다.&lt;/p&gt;
&lt;p data-end=&quot;2017&quot; data-start=&quot;1991&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AI가 문제를 대신 해결한 것은 아니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2074&quot; data-start=&quot;2019&quot; data-ke-size=&quot;size16&quot;&gt;공식적인 판단은 결국 해당 기관이 해야 하고, 법적인 판단이 필요한 경우 전문가의 검토도 필요하다.&lt;/p&gt;
&lt;p data-end=&quot;2099&quot; data-start=&quot;2076&quot; data-ke-size=&quot;size16&quot;&gt;AI가 할 수 없는 영역도 분명히 있었다.&lt;/p&gt;
&lt;p data-end=&quot;2135&quot; data-start=&quot;2101&quot; data-ke-size=&quot;size16&quot;&gt;사진만으로 시설의 정확한 사양을 100% 확정할 수는 없었다.&lt;/p&gt;
&lt;p data-end=&quot;2158&quot; data-start=&quot;2137&quot; data-ke-size=&quot;size16&quot;&gt;오래된 도면도 바로 꺼내올 수 없었다.&lt;/p&gt;
&lt;p data-end=&quot;2181&quot; data-start=&quot;2160&quot; data-ke-size=&quot;size16&quot;&gt;그리고 중간중간 추정이 틀리기도 했다.&lt;/p&gt;
&lt;p data-end=&quot;2197&quot; data-start=&quot;2183&quot; data-ke-size=&quot;size16&quot;&gt;그런데도 굉장히 유용했다.&lt;/p&gt;
&lt;p data-end=&quot;2224&quot; data-start=&quot;2199&quot; data-ke-size=&quot;size16&quot;&gt;왜냐하면 AI가 한 일은 정답을 주는 것보다,&lt;/p&gt;
&lt;p data-end=&quot;2267&quot; data-start=&quot;2226&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 문제를 풀 수 있는 상태로 만들어주는 것&lt;/b&gt;에 가까웠기 때문이다.&lt;/p&gt;
&lt;hr data-end=&quot;2272&quot; data-start=&quot;2269&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2294&quot; data-start=&quot;2274&quot; data-ke-size=&quot;size26&quot;&gt;현실 문제도 디버깅할 수 있었다&lt;/h2&gt;
&lt;p data-end=&quot;2329&quot; data-start=&quot;2296&quot; data-ke-size=&quot;size16&quot;&gt;이번에 내가 사용한 흐름을 개발식으로 표현하면 대략 이랬다.&lt;/p&gt;
&lt;p data-end=&quot;2405&quot; data-start=&quot;2331&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;문제 발견 &amp;rarr; 자료 확보 &amp;rarr; 가설 설정 &amp;rarr; 공식자료 확인 &amp;rarr; 지도 검증 &amp;rarr; 가설 수정 &amp;rarr; 필요한 정보 특정 &amp;rarr; 실제 행동 준비&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2439&quot; data-start=&quot;2407&quot; data-ke-size=&quot;size16&quot;&gt;코드에서 버그를 찾을 때 하는 행동과 크게 다르지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;2474&quot; data-start=&quot;2441&quot; data-ke-size=&quot;size16&quot;&gt;어쩌면 AI의 가장 강력한 사용법은 여기 있는지도 모르겠다.&lt;/p&gt;
&lt;p data-end=&quot;2495&quot; data-start=&quot;2476&quot; data-ke-size=&quot;size16&quot;&gt;모르는 것을 그냥 물어보는 것보다,&lt;/p&gt;
&lt;p data-end=&quot;2537&quot; data-start=&quot;2497&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;복잡한 문제를 잘게 쪼개고 다음 행동을 결정하는 데 사용하는 것.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;2542&quot; data-start=&quot;2539&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2570&quot; data-start=&quot;2544&quot; data-ke-size=&quot;size26&quot;&gt;AI를 잘 쓴다는 건 질문을 잘하는 것보다&lt;/h2&gt;
&lt;p data-end=&quot;2611&quot; data-start=&quot;2572&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 프롬프트를 잘 쓰는 것이 AI를 잘 쓰는 방법이라고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;2621&quot; data-start=&quot;2613&quot; data-ke-size=&quot;size16&quot;&gt;물론 중요하다.&lt;/p&gt;
&lt;p data-end=&quot;2643&quot; data-start=&quot;2623&quot; data-ke-size=&quot;size16&quot;&gt;그런데 지금은 조금 다르게 생각한다.&lt;/p&gt;
&lt;p data-end=&quot;2663&quot; data-start=&quot;2645&quot; data-ke-size=&quot;size16&quot;&gt;좋은 질문 한 번보다 중요한 것은&lt;/p&gt;
&lt;p data-end=&quot;2723&quot; data-start=&quot;2665&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;자료를 주고, 답을 검증하고, 다시 자료를 찾고, 틀린 부분을 수정하면서 계속 진행하는 것&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;2757&quot; data-start=&quot;2725&quot; data-ke-size=&quot;size16&quot;&gt;AI에게 정답을 요구하는 게 아니라 같이 조사하는 것이다.&lt;/p&gt;
&lt;p data-end=&quot;2770&quot; data-start=&quot;2759&quot; data-ke-size=&quot;size16&quot;&gt;그리고 꽤 재미있다.&lt;/p&gt;
&lt;p data-end=&quot;2829&quot; data-start=&quot;2772&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 전혀 모르는 분야였는데 몇 시간 뒤에는 적어도 전문가에게 무엇을 물어봐야 하는지는 알게 된다.&lt;/p&gt;
&lt;p data-end=&quot;2845&quot; data-start=&quot;2831&quot; data-ke-size=&quot;size16&quot;&gt;그 차이가 생각보다 크다.&lt;/p&gt;</description>
      <category>AI TOOLS</category>
      <category>ai도구</category>
      <category>AI사용법</category>
      <category>AI활용</category>
      <category>ChatGPT</category>
      <category>Nocklock</category>
      <category>문제해결</category>
      <category>생성형AI</category>
      <category>업무자동화</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/27</guid>
      <comments>https://nocklock.tistory.com/27#entry27comment</comments>
      <pubDate>Wed, 23 Sep 2026 08:36:02 +0900</pubDate>
    </item>
    <item>
      <title>개발자 노트북 RAM 32GB&amp;middot;SSD 1TB면 충분할까? 그램 17 고르며 고민한 기준</title>
      <link>https://nocklock.tistory.com/38</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 23일 오전 08_04_31.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSodwP/dJMcaiSwLkV/B8mvFV9y7Nlqu1ykunB6D1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSodwP/dJMcaiSwLkV/B8mvFV9y7Nlqu1ykunB6D1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSodwP/dJMcaiSwLkV/B8mvFV9y7Nlqu1ykunB6D1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSodwP%2FdJMcaiSwLkV%2FB8mvFV9y7Nlqu1ykunB6D1%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; alt=&quot;충분할까&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 23일 오전 08_04_31.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div id=&quot;code_1790119401329&quot; data-ke-type=&quot;html&quot; data-source=&quot;&amp;lt;p style=&amp;quot;font-size:13px; color:#777; margin:12px 0 28px 0;&amp;quot;&amp;gt;
※ 이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
&amp;lt;/p&amp;gt;&quot;&gt;
&lt;p style=&quot;font-size: 13px; color: #777; margin: 12px 0 28px 0;&quot; data-ke-size=&quot;size16&quot;&gt;※ 이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;p data-end=&quot;613&quot; data-start=&quot;573&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;613&quot; data-start=&quot;573&quot; data-ke-size=&quot;size16&quot;&gt;노트북을 사려고 알아보기 시작했을 때는 CPU가 제일 중요할 줄 알았다.&lt;/p&gt;
&lt;p data-end=&quot;653&quot; data-start=&quot;615&quot; data-ke-size=&quot;size16&quot;&gt;Ultra 7이냐, 다른 CPU냐.&lt;br /&gt;외장 그래픽이 있느냐 없느냐.&lt;/p&gt;
&lt;p data-end=&quot;698&quot; data-start=&quot;655&quot; data-ke-size=&quot;size16&quot;&gt;그런데 막상 제품을 하나씩 보다 보니 오히려 더 오래 고민한 건 따로 있었다.&lt;/p&gt;
&lt;p data-end=&quot;720&quot; data-start=&quot;700&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RAM은 32GB면 충분한가?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;725&quot; data-start=&quot;722&quot; data-ke-size=&quot;size16&quot;&gt;그리고&lt;/p&gt;
&lt;p data-end=&quot;774&quot; data-start=&quot;727&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SSD는 512GB로 시작해도 되는가, 아니면 처음부터 1TB로 가야 하는가?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;812&quot; data-start=&quot;776&quot; data-ke-size=&quot;size16&quot;&gt;나는 결국 LG 그램 17 Ultra 7 구독으로 방향을 정했다.&lt;/p&gt;
&lt;p data-end=&quot;854&quot; data-start=&quot;814&quot; data-ke-size=&quot;size16&quot;&gt;그런데 노트북을 정하고 나서도 저장공간 때문에 한동안 계산기를 두드렸다.&lt;/p&gt;
&lt;p data-end=&quot;884&quot; data-start=&quot;856&quot; data-ke-size=&quot;size16&quot;&gt;512GB로 시작할지, SSD를 하나 더 추가할지.&lt;/p&gt;
&lt;p data-end=&quot;931&quot; data-start=&quot;886&quot; data-ke-size=&quot;size16&quot;&gt;그러다 보니 어느 순간 나는 노트북을 사는 건지 저장장치를 사는 건지 모르겠더라.&lt;/p&gt;
&lt;hr data-end=&quot;936&quot; data-start=&quot;933&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;966&quot; data-start=&quot;938&quot; data-section-id=&quot;72hsag&quot; data-ke-size=&quot;size26&quot;&gt;개발만 한다면 RAM 16GB도 되지 않을까?&lt;/h2&gt;
&lt;p data-end=&quot;971&quot; data-start=&quot;968&quot; data-ke-size=&quot;size16&quot;&gt;된다.&lt;/p&gt;
&lt;p data-end=&quot;995&quot; data-start=&quot;973&quot; data-ke-size=&quot;size16&quot;&gt;이건 먼저 말하고 시작해야 할 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;1054&quot; data-start=&quot;997&quot; data-ke-size=&quot;size16&quot;&gt;Java 하나 띄우고 IntelliJ 하나 켜서 코딩한다고 갑자기 RAM 32GB가 필요한 건 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1125&quot; data-start=&quot;1056&quot; data-ke-size=&quot;size16&quot;&gt;나도 예전에 개발할 때를 생각해보면 그냥 IDE 켜고 브라우저 몇 개 띄우는 정도라면 16GB에서도 개발은 충분히 가능하다.&lt;/p&gt;
&lt;p data-end=&quot;1163&quot; data-start=&quot;1127&quot; data-ke-size=&quot;size16&quot;&gt;문제는 요즘 내가 개발하는 모습이 더 이상 그렇지 않다는 거였다.&lt;/p&gt;
&lt;p data-end=&quot;1192&quot; data-start=&quot;1165&quot; data-ke-size=&quot;size16&quot;&gt;보통 작업을 시작하면 이런 것들이 같이 떠 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1307&quot; data-start=&quot;1194&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1204&quot; data-start=&quot;1194&quot; data-section-id=&quot;1njpu2l&quot;&gt;IntelliJ&lt;/li&gt;
&lt;li data-end=&quot;1218&quot; data-start=&quot;1205&quot; data-section-id=&quot;rvusbz&quot;&gt;Spring Boot&lt;/li&gt;
&lt;li data-end=&quot;1234&quot; data-start=&quot;1219&quot; data-section-id=&quot;1hxnsh3&quot;&gt;Chrome 탭 여러 개&lt;/li&gt;
&lt;li data-end=&quot;1247&quot; data-start=&quot;1235&quot; data-section-id=&quot;ozxyby&quot;&gt;DB 관련 프로그램&lt;/li&gt;
&lt;li data-end=&quot;1253&quot; data-start=&quot;1248&quot; data-section-id=&quot;1o4hle&quot;&gt;Git&lt;/li&gt;
&lt;li data-end=&quot;1262&quot; data-start=&quot;1254&quot; data-section-id=&quot;1u6gra4&quot;&gt;Docker&lt;/li&gt;
&lt;li data-end=&quot;1280&quot; data-start=&quot;1263&quot; data-section-id=&quot;170lw0n&quot;&gt;ChatGPT나 Claude&lt;/li&gt;
&lt;li data-end=&quot;1293&quot; data-start=&quot;1281&quot; data-section-id=&quot;1dv0gkp&quot;&gt;문서나 Notion&lt;/li&gt;
&lt;li data-end=&quot;1307&quot; data-start=&quot;1294&quot; data-section-id=&quot;16roe5d&quot;&gt;가끔 로컬 AI 환경&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1323&quot; data-start=&quot;1309&quot; data-ke-size=&quot;size16&quot;&gt;하나씩 보면 별것 아닌데,&lt;/p&gt;
&lt;p data-end=&quot;1349&quot; data-start=&quot;1325&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이게 한꺼번에 켜져 있는 게 문제다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1385&quot; data-start=&quot;1351&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번에는 '프로그램 하나를 실행할 수 있느냐'가 아니라&lt;/p&gt;
&lt;blockquote data-end=&quot;1429&quot; data-start=&quot;1387&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1429&quot; data-start=&quot;1389&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 평소 작업하듯 이것저것 다 켜놓고도 신경 쓰지 않아도 되느냐&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1441&quot; data-start=&quot;1431&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1441&quot; data-start=&quot;1431&quot; data-ke-size=&quot;size16&quot;&gt;를 기준으로 봤다.&lt;/p&gt;
&lt;hr data-end=&quot;1446&quot; data-start=&quot;1443&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1473&quot; data-start=&quot;1448&quot; data-section-id=&quot;16fxh3m&quot; data-ke-size=&quot;size26&quot;&gt;그래서 RAM 32GB를 기준으로 잡았다&lt;/h2&gt;
&lt;p data-end=&quot;1505&quot; data-start=&quot;1475&quot; data-ke-size=&quot;size16&quot;&gt;32GB가 개발자의 필수 사양이라고 생각하지는 않는다.&lt;/p&gt;
&lt;p data-end=&quot;1522&quot; data-start=&quot;1507&quot; data-ke-size=&quot;size16&quot;&gt;웹 개발을 배우는 단계이고,&lt;/p&gt;
&lt;p data-end=&quot;1582&quot; data-start=&quot;1524&quot; data-ke-size=&quot;size16&quot;&gt;VS Code나 IntelliJ 하나와 브라우저 정도가 주 작업이라면 16GB도 충분히 시작할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1613&quot; data-start=&quot;1584&quot; data-ke-size=&quot;size16&quot;&gt;그런데 나는 앞으로 몇 년 쓸 노트북을 보고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1639&quot; data-start=&quot;1615&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot만 할 생각도 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;1714&quot; data-start=&quot;1641&quot; data-ke-size=&quot;size16&quot;&gt;Docker도 계속 써야 하고,&lt;br /&gt;AI 관련 개발도 해보고 있고,&lt;br /&gt;Ollama 같은 로컬 AI도 직접 이것저것 만져보고 있다.&lt;/p&gt;
&lt;p data-end=&quot;1735&quot; data-start=&quot;1716&quot; data-ke-size=&quot;size16&quot;&gt;그러다 보니 16GB를 사고 나중에&lt;/p&gt;
&lt;p data-end=&quot;1757&quot; data-start=&quot;1737&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;그때 그냥 32GB 할걸.&quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1774&quot; data-start=&quot;1759&quot; data-ke-size=&quot;size16&quot;&gt;하는 상황은 피하고 싶었다.&lt;/p&gt;
&lt;p data-end=&quot;1820&quot; data-start=&quot;1776&quot; data-ke-size=&quot;size16&quot;&gt;특히 요즘 얇은 노트북들은 RAM을 나중에 마음대로 늘릴 수 없는 경우도 많다.&lt;/p&gt;
&lt;p data-end=&quot;1867&quot; data-start=&quot;1822&quot; data-ke-size=&quot;size16&quot;&gt;SSD야 방법을 찾을 수 있어도 RAM은 처음 살 때 결정이 끝나는 경우가 있다.&lt;/p&gt;
&lt;p data-end=&quot;1886&quot; data-start=&quot;1869&quot; data-ke-size=&quot;size16&quot;&gt;그래서 나한테 RAM 32GB는&lt;/p&gt;
&lt;p data-end=&quot;1943&quot; data-start=&quot;1888&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;고성능 옵션이라기보다는 몇 년 동안 용량을 신경 쓰지 않기 위해 사는 여유 공간&lt;/b&gt;에 가까웠다.&lt;/p&gt;
&lt;hr data-end=&quot;1948&quot; data-start=&quot;1945&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1970&quot; data-start=&quot;1950&quot; data-section-id=&quot;guxf6p&quot; data-ke-size=&quot;size26&quot;&gt;그러면 64GB까지 가야 할까?&lt;/h2&gt;
&lt;p data-end=&quot;1990&quot; data-start=&quot;1972&quot; data-ke-size=&quot;size16&quot;&gt;여기서 또 인간의 욕심이 나온다.&lt;/p&gt;
&lt;p data-end=&quot;2015&quot; data-start=&quot;1992&quot; data-ke-size=&quot;size16&quot;&gt;32GB를 보고 있으면 64GB가 보인다.&lt;/p&gt;
&lt;p data-end=&quot;2044&quot; data-start=&quot;2017&quot; data-ke-size=&quot;size16&quot;&gt;512GB SSD를 보고 있으면 1TB가 보이고,&lt;/p&gt;
&lt;p data-end=&quot;2068&quot; data-start=&quot;2046&quot; data-ke-size=&quot;size16&quot;&gt;1TB를 보다 보면 또 2TB가 보인다.&lt;/p&gt;
&lt;p data-end=&quot;2097&quot; data-start=&quot;2070&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 하다 보면 노트북 가격이 끝없이 올라간다.&lt;/p&gt;
&lt;p data-end=&quot;2124&quot; data-start=&quot;2099&quot; data-ke-size=&quot;size16&quot;&gt;내 기준에서는 RAM 64GB는 일단 멈췄다.&lt;/p&gt;
&lt;p data-end=&quot;2200&quot; data-start=&quot;2126&quot; data-ke-size=&quot;size16&quot;&gt;대규모 가상머신을 여러 개 돌리거나,&lt;br /&gt;무거운 데이터 작업을 하거나,&lt;br /&gt;로컬 AI를 본격적인 워크스테이션처럼 사용하는 게 아니라면&lt;/p&gt;
&lt;p data-end=&quot;2252&quot; data-start=&quot;2202&quot; data-ke-size=&quot;size16&quot;&gt;현재 내가 하는 Java/Spring 개발에서 64GB까지 올려야 할 이유는 크지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;2292&quot; data-start=&quot;2254&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;필요할 수도 있는 사양과 지금 실제로 필요한 사양은 다르니까.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2320&quot; data-start=&quot;2294&quot; data-ke-size=&quot;size16&quot;&gt;이번 노트북을 고르면서 이걸 꽤 많이 생각했다.&lt;/p&gt;
&lt;hr data-end=&quot;2325&quot; data-start=&quot;2322&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2347&quot; data-start=&quot;2327&quot; data-section-id=&quot;1b827dm&quot;&gt;오히려 더 고민됐던 건 SSD였다&lt;/h1&gt;
&lt;p data-end=&quot;2367&quot; data-start=&quot;2349&quot; data-ke-size=&quot;size16&quot;&gt;RAM보다 SSD가 더 애매했다.&lt;/p&gt;
&lt;p data-end=&quot;2405&quot; data-start=&quot;2369&quot; data-ke-size=&quot;size16&quot;&gt;내가 알아본 그램 17은 512GB SSD가 들어가는 구성이었다.&lt;/p&gt;
&lt;p data-end=&quot;2417&quot; data-start=&quot;2407&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 생각했다.&lt;/p&gt;
&lt;blockquote data-end=&quot;2433&quot; data-start=&quot;2419&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2433&quot; data-start=&quot;2421&quot; data-ke-size=&quot;size16&quot;&gt;512GB면 꽤 큰데?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2471&quot; data-start=&quot;2435&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2471&quot; data-start=&quot;2435&quot; data-ke-size=&quot;size16&quot;&gt;그런데 개발하면서 컴퓨터에 쌓이는 걸 하나씩 생각해보기 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;2481&quot; data-start=&quot;2473&quot; data-ke-size=&quot;size16&quot;&gt;JDK도 깔고,&lt;/p&gt;
&lt;p data-end=&quot;2496&quot; data-start=&quot;2483&quot; data-ke-size=&quot;size16&quot;&gt;IntelliJ도 깔고,&lt;/p&gt;
&lt;p data-end=&quot;2508&quot; data-start=&quot;2498&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트도 쌓이고,&lt;/p&gt;
&lt;p data-end=&quot;2526&quot; data-start=&quot;2510&quot; data-ke-size=&quot;size16&quot;&gt;Docker 이미지도 생기고,&lt;/p&gt;
&lt;p data-end=&quot;2542&quot; data-start=&quot;2528&quot; data-ke-size=&quot;size16&quot;&gt;Git 저장소도 늘어나고,&lt;/p&gt;
&lt;p data-end=&quot;2563&quot; data-start=&quot;2544&quot; data-ke-size=&quot;size16&quot;&gt;각종 SDK와 개발도구도 설치한다.&lt;/p&gt;
&lt;p data-end=&quot;2622&quot; data-start=&quot;2565&quot; data-ke-size=&quot;size16&quot;&gt;여기에 사진이나 영상 같은 개인 파일까지 조금씩 들어오기 시작하면 512GB가 생각보다 넓지만은 않다.&lt;/p&gt;
&lt;p data-end=&quot;2667&quot; data-start=&quot;2624&quot; data-ke-size=&quot;size16&quot;&gt;특히 Docker를 사용하기 시작하면서 저장공간에 대한 생각이 조금 달라졌다.&lt;/p&gt;
&lt;p data-end=&quot;2708&quot; data-start=&quot;2669&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너만 보면 작아 보이는데 이미지가 계속 쌓이기 시작하면 어느 순간&lt;/p&gt;
&lt;p data-end=&quot;2729&quot; data-start=&quot;2710&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;얘네가 왜 이렇게 많지?&quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2741&quot; data-start=&quot;2731&quot; data-ke-size=&quot;size16&quot;&gt;하는 순간이 온다.&lt;/p&gt;
&lt;hr data-end=&quot;2746&quot; data-start=&quot;2743&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2775&quot; data-start=&quot;2748&quot; data-section-id=&quot;1re5kgl&quot; data-ke-size=&quot;size26&quot;&gt;개발자 노트북 SSD 512GB면 부족할까?&lt;/h2&gt;
&lt;p data-end=&quot;2791&quot; data-start=&quot;2777&quot; data-ke-size=&quot;size16&quot;&gt;이것도 RAM하고 똑같다.&lt;/p&gt;
&lt;p data-end=&quot;2828&quot; data-start=&quot;2793&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;512GB로 개발할 수 있냐고 하면 당연히 할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2888&quot; data-start=&quot;2830&quot; data-ke-size=&quot;size16&quot;&gt;오히려 프로젝트를 Git에 잘 관리하고, 대용량 파일을 별도로 보관한다면 꽤 오랫동안 사용할 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;2906&quot; data-start=&quot;2890&quot; data-ke-size=&quot;size16&quot;&gt;그래서 나는 이렇게 정리했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;사용 방식SSD
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;3047&quot; data-start=&quot;2908&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;3047&quot; data-start=&quot;2935&quot;&gt;
&lt;tr data-end=&quot;2964&quot; data-start=&quot;2935&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2951&quot; data-start=&quot;2935&quot;&gt;코딩&amp;middot;문서&amp;middot;웹 개발 위주&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2964&quot; data-start=&quot;2951&quot;&gt;512GB도 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3009&quot; data-start=&quot;2965&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2995&quot; data-start=&quot;2965&quot;&gt;IntelliJ + Docker + 여러 개발도구&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3009&quot; data-start=&quot;2995&quot;&gt;1TB가 마음 편함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3047&quot; data-start=&quot;3010&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3034&quot; data-start=&quot;3010&quot;&gt;영상&amp;middot;AI 모델&amp;middot;대용량 데이터까지 저장&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3047&quot; data-start=&quot;3034&quot;&gt;1TB 이상 고려&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3073&quot; data-start=&quot;3049&quot; data-ke-size=&quot;size16&quot;&gt;내 경우에는 가운데와 마지막 사이쯤 있었다.&lt;/p&gt;
&lt;p data-end=&quot;3116&quot; data-start=&quot;3075&quot; data-ke-size=&quot;size16&quot;&gt;일반적인 Java 개발도 하지만 앞으로 로컬 AI도 계속 만져볼 생각이다.&lt;/p&gt;
&lt;p data-end=&quot;3167&quot; data-start=&quot;3118&quot; data-ke-size=&quot;size16&quot;&gt;그래서 &lt;b&gt;새로 산다면 1TB 정도가 가장 편하지 않을까&lt;/b&gt;라는 쪽으로 생각이 기울었다.&lt;/p&gt;
&lt;hr data-end=&quot;3172&quot; data-start=&quot;3169&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3199&quot; data-start=&quot;3174&quot; data-section-id=&quot;n73ya2&quot;&gt;그런데 나는 1.5TB까지 계산하고 있었다&lt;/h1&gt;
&lt;p data-end=&quot;3219&quot; data-start=&quot;3201&quot; data-ke-size=&quot;size16&quot;&gt;여기서 조금 웃긴 상황이 생겼다.&lt;/p&gt;
&lt;p data-end=&quot;3240&quot; data-start=&quot;3221&quot; data-ke-size=&quot;size16&quot;&gt;512GB가 기본으로 들어가 있으니&lt;/p&gt;
&lt;p data-end=&quot;3255&quot; data-start=&quot;3242&quot; data-ke-size=&quot;size16&quot;&gt;SSD 하나를 추가하면?&lt;/p&gt;
&lt;p data-end=&quot;3276&quot; data-start=&quot;3257&quot; data-ke-size=&quot;size16&quot;&gt;1TB를 더 넣으면 총 1.5TB.&lt;/p&gt;
&lt;p data-end=&quot;3291&quot; data-start=&quot;3278&quot; data-ke-size=&quot;size16&quot;&gt;그러다 가격을 알아보고,&lt;/p&gt;
&lt;p data-end=&quot;3314&quot; data-start=&quot;3293&quot; data-ke-size=&quot;size16&quot;&gt;노트북 가격에 SSD 가격까지 더하고,&lt;/p&gt;
&lt;p data-end=&quot;3338&quot; data-start=&quot;3316&quot; data-ke-size=&quot;size16&quot;&gt;또 다른 모델 가격을 비교하기 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;3372&quot; data-start=&quot;3340&quot; data-ke-size=&quot;size16&quot;&gt;노트북 하나 사는데 엑셀이라도 만들어야 할 분위기가 됐다.&lt;/p&gt;
&lt;p data-end=&quot;3386&quot; data-start=&quot;3374&quot; data-ke-size=&quot;size16&quot;&gt;그러다 다시 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;3413&quot; data-start=&quot;3388&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 오늘 당장 1.5TB가 필요한가?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3419&quot; data-start=&quot;3415&quot; data-ke-size=&quot;size16&quot;&gt;아니다.&lt;/p&gt;
&lt;p data-end=&quot;3464&quot; data-start=&quot;3421&quot; data-ke-size=&quot;size16&quot;&gt;결국 저장공간은 실제로 부족해질 때 확장할 방법이 있다면 그때 판단해도 된다.&lt;/p&gt;
&lt;p data-end=&quot;3507&quot; data-start=&quot;3466&quot; data-ke-size=&quot;size16&quot;&gt;반면 RAM처럼 나중에 바꾸기 어려운 것은 처음 선택이 조금 더 중요하다.&lt;/p&gt;
&lt;p data-end=&quot;3530&quot; data-start=&quot;3509&quot; data-ke-size=&quot;size16&quot;&gt;이 기준으로 생각하니 조금 간단해졌다.&lt;/p&gt;
&lt;hr data-end=&quot;3535&quot; data-start=&quot;3532&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3567&quot; data-start=&quot;3537&quot; data-section-id=&quot;1w1s2o6&quot;&gt;지금 다시 고른다면 RAM에 먼저 돈을 쓸 것 같다&lt;/h1&gt;
&lt;p data-end=&quot;3579&quot; data-start=&quot;3569&quot; data-ke-size=&quot;size16&quot;&gt;예산이 한정돼 있고&lt;/p&gt;
&lt;p data-end=&quot;3602&quot; data-start=&quot;3581&quot; data-ke-size=&quot;size16&quot;&gt;둘 중 하나만 올릴 수 있다고 해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3647&quot; data-start=&quot;3604&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3624&quot; data-start=&quot;3604&quot; data-section-id=&quot;18memd8&quot;&gt;RAM 16GB + SSD 1TB&lt;/li&gt;
&lt;li data-end=&quot;3647&quot; data-start=&quot;3625&quot; data-section-id=&quot;1x2jxke&quot;&gt;RAM 32GB + SSD 512GB&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3702&quot; data-start=&quot;3649&quot; data-ke-size=&quot;size16&quot;&gt;나라면 개발용 노트북에서는 &lt;b&gt;32GB RAM + 512GB SSD 쪽을 먼저 볼 것 같다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3702&quot; data-start=&quot;3649&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2454&quot; data-start=&quot;2392&quot; data-ke-size=&quot;size16&quot;&gt;SSD는 조금 다르다.&lt;br /&gt;저장공간이 부족해진 뒤에도 추가 SSD나 외장 SSD처럼 해결할 방법이 있다.&lt;/p&gt;
&lt;p data-end=&quot;2539&quot; data-start=&quot;2462&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번에는 처음부터 모든 용량을 최대한 크게 넣기보다, RAM처럼 나중에 바꾸기 어려운 부분에 먼저 돈을 쓰는 쪽이 낫다고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;2539&quot; data-start=&quot;2462&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3768&quot; data-start=&quot;3750&quot; data-ke-size=&quot;size16&quot;&gt;하지만 온보드 RAM이라면 나중에&lt;/p&gt;
&lt;blockquote data-end=&quot;3793&quot; data-start=&quot;3770&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;3793&quot; data-start=&quot;3772&quot; data-ke-size=&quot;size16&quot;&gt;RAM이 부족하니 하나 더 꽂아야겠다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;3807&quot; data-start=&quot;3795&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3807&quot; data-start=&quot;3795&quot; data-ke-size=&quot;size16&quot;&gt;가 안 될 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;3815&quot; data-start=&quot;3809&quot; data-ke-size=&quot;size16&quot;&gt;그래서 나는&lt;/p&gt;
&lt;p data-end=&quot;3840&quot; data-start=&quot;3817&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RAM &amp;rarr; 나중에 바꾸기 어려운 것&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3874&quot; data-start=&quot;3842&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SSD &amp;rarr; 부족해지면 해결 방법을 찾을 수 있는 것&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3884&quot; data-start=&quot;3876&quot; data-ke-size=&quot;size16&quot;&gt;으로 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;3906&quot; data-start=&quot;3886&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 보니 선택하기가 훨씬 쉬웠다.&lt;/p&gt;
&lt;hr data-end=&quot;3911&quot; data-start=&quot;3908&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3938&quot; data-start=&quot;3913&quot; data-section-id=&quot;1hgprqa&quot;&gt;결국 내 기준은 32GB + 1TB 정도다&lt;/h1&gt;
&lt;p data-end=&quot;3975&quot; data-start=&quot;3940&quot; data-ke-size=&quot;size16&quot;&gt;이번에 개발용 노트북을 알아보면서 내린 결론은 의외로 평범했다.&lt;/p&gt;
&lt;h3 data-end=&quot;3990&quot; data-start=&quot;3977&quot; data-section-id=&quot;1kua097&quot; data-ke-size=&quot;size23&quot;&gt;가볍게 개발한다면&lt;/h3&gt;
&lt;p data-end=&quot;4016&quot; data-start=&quot;3992&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RAM 16GB + SSD 512GB&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4038&quot; data-start=&quot;4018&quot; data-ke-size=&quot;size16&quot;&gt;이 정도로도 충분히 시작할 수 있다.&lt;/p&gt;
&lt;h3 data-end=&quot;4067&quot; data-start=&quot;4040&quot; data-section-id=&quot;1gzquge&quot; data-ke-size=&quot;size23&quot;&gt;여러 프로그램을 동시에 사용하는 개발자라면&lt;/h3&gt;
&lt;p data-end=&quot;4091&quot; data-start=&quot;4069&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RAM 32GB + SSD 1TB&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4123&quot; data-start=&quot;4093&quot; data-ke-size=&quot;size16&quot;&gt;개인적으로는 이 정도가 가장 편한 구간이라고 생각한다.&lt;/p&gt;
&lt;h3 data-end=&quot;4161&quot; data-start=&quot;4125&quot; data-section-id=&quot;15za09u&quot; data-ke-size=&quot;size23&quot;&gt;VM&amp;middot;로컬 AI&amp;middot;영상&amp;middot;대용량 데이터까지 본격적으로 다룬다면&lt;/h3&gt;
&lt;p data-end=&quot;4199&quot; data-start=&quot;4163&quot; data-ke-size=&quot;size16&quot;&gt;32GB 이상과 1TB 이상의 저장공간을 그때부터 고민하면 된다.&lt;/p&gt;
&lt;p data-end=&quot;4206&quot; data-start=&quot;4201&quot; data-ke-size=&quot;size16&quot;&gt;중요한 건&lt;/p&gt;
&lt;p data-end=&quot;4240&quot; data-start=&quot;4208&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'개발자는 무조건 32GB가 필요하다'가 아니었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4278&quot; data-start=&quot;4242&quot; data-ke-size=&quot;size16&quot;&gt;내가 실제로 어떤 프로그램을 동시에 사용하는지 보는 게 먼저였다.&lt;/p&gt;
&lt;hr data-end=&quot;4283&quot; data-start=&quot;4280&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;4312&quot; data-start=&quot;4285&quot; data-section-id=&quot;zvpkc3&quot; data-ke-size=&quot;size26&quot;&gt;나는 결국 그램 17 Ultra 7을 골랐다&lt;/h2&gt;
&lt;p data-end=&quot;4334&quot; data-start=&quot;4314&quot; data-ke-size=&quot;size16&quot;&gt;이번 노트북 선택에서 재미있었던 건,&lt;/p&gt;
&lt;p data-end=&quot;4360&quot; data-start=&quot;4336&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 성능 숫자만 보고 있었다는 것이다.&lt;/p&gt;
&lt;p data-end=&quot;4406&quot; data-start=&quot;4362&quot; data-ke-size=&quot;size16&quot;&gt;RTX 5050도 보고,&lt;br /&gt;5070도 보고,&lt;br /&gt;SSD 용량도 계속 올려봤다.&lt;/p&gt;
&lt;p data-end=&quot;4431&quot; data-start=&quot;4408&quot; data-ke-size=&quot;size16&quot;&gt;그런데 마지막에 남은 건 의외로 단순했다.&lt;/p&gt;
&lt;p data-end=&quot;4454&quot; data-start=&quot;4433&quot; data-ke-size=&quot;size16&quot;&gt;내가 이 노트북으로 가장 많이 할 것은&lt;/p&gt;
&lt;p data-end=&quot;4485&quot; data-start=&quot;4456&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;코딩하고, 찾아보고, 글 쓰고, 개발하는 것.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4509&quot; data-start=&quot;4487&quot; data-ke-size=&quot;size16&quot;&gt;그래서 모든 사양을 최고로 만드는 것보다&lt;/p&gt;
&lt;p data-end=&quot;4551&quot; data-start=&quot;4511&quot; data-ke-size=&quot;size16&quot;&gt;내가 매일 사용할 때 불편하지 않은 구성을 고르는 쪽으로 방향을 바꿨다.&lt;/p&gt;
&lt;p data-end=&quot;4584&quot; data-start=&quot;4553&quot; data-ke-size=&quot;size16&quot;&gt;그리고 결국 그램 17 Ultra 7 구독으로 결정했다.&lt;/p&gt;
&lt;p data-end=&quot;4600&quot; data-start=&quot;4586&quot; data-ke-size=&quot;size16&quot;&gt;아직 여기서 끝은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;4662&quot; data-start=&quot;4602&quot; data-ke-size=&quot;size16&quot;&gt;실제로 노트북이 오면 IntelliJ부터 Docker까지 내가 사용하는 개발환경을 그대로 세팅해볼 생각이다.&lt;/p&gt;
&lt;p data-end=&quot;4681&quot; data-start=&quot;4664&quot; data-ke-size=&quot;size16&quot;&gt;그리고 궁금한 것도 하나 있다.&lt;/p&gt;
&lt;p data-end=&quot;4719&quot; data-start=&quot;4683&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이 노트북에서 Ollama를 실제로 돌리면 어느 정도일까?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4741&quot; data-start=&quot;4721&quot; data-ke-size=&quot;size16&quot;&gt;이건 직접 돌려보고 다시 써봐야겠다.&lt;/p&gt;
&lt;hr data-end=&quot;4746&quot; data-start=&quot;4743&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;div id=&quot;code_1790117910320&quot; data-ke-type=&quot;html&quot; data-source=&quot;&amp;lt;hr&amp;gt;

&amp;lt;h2&amp;gt;같이 읽으면 좋은 글&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;
  &amp;lt;a href=&amp;quot;https://nocklock.tistory.com/33&amp;quot;&amp;gt;
2026 개발자 노트북 추천 &amp;mdash; 입문용&amp;middot;실무용&amp;middot;휴대용으로 나눠봤다
&amp;lt;/a&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
  &amp;lt;a href=&amp;quot;https://nocklock.tistory.com/34&amp;quot;&amp;gt;
LG 그램 Pro 17 개발용으로 괜찮을까? AI&amp;middot;Ollama 때문에 RTX 5050까지 고민했다
&amp;lt;/a&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;hr&amp;gt;

&amp;lt;h2&amp;gt;노트북을 고르면서 같이 보고 있는 것들&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;
노트북을 알아보다 보니 저장공간이나 포트처럼
노트북 사양만으로 끝나지 않는 부분도 있었다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
아직 직접 사용한 제품에 대한 후기는 아니고,
이번에 노트북을 준비하면서 같이 비교하고 있는 제품들이다.
&amp;lt;/p&amp;gt;

&amp;lt;h3&amp;gt;삼성전자 Portable SSD T7 Shield 1TB&amp;lt;/h3&amp;gt;

&amp;lt;p&amp;gt;
512GB를 사용하다 저장공간이 부족해진다면
내장 SSD를 바로 늘리는 것 말고 외장 SSD를 사용하는 방법도 있다.
&amp;lt;/p&amp;gt;

&amp;lt;div style=&amp;quot;margin:24px 0;&amp;quot;&amp;gt;
  &amp;lt;a href=&amp;quot;https://link.coupang.com/a/hgxSD1eJoa&amp;quot;
     target=&amp;quot;_blank&amp;quot;
     rel=&amp;quot;sponsored nofollow noopener&amp;quot;
     style=&amp;quot;
       display:block;
       width:100%;
       box-sizing:border-box;
       padding:17px 20px;
       background:#17212d;
       border:1px solid #6fe6c1;
       border-radius:12px;
       color:#ffffff;
       text-align:center;
       text-decoration:none;
       font-size:16px;
       font-weight:700;
     &amp;quot;&amp;gt;
    삼성 T7 Shield 1TB &amp;mdash; 쿠팡에서 현재 가격 확인하기 &amp;rarr;
  &amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;h3&amp;gt;USB-C 멀티허브&amp;lt;/h3&amp;gt;

&amp;lt;p&amp;gt;
밖에서는 노트북 자체로 사용하더라도
집에서는 모니터나 USB 장치를 연결할 일이 많아
USB-C 허브도 같이 보고 있다.
&amp;lt;/p&amp;gt;

&amp;lt;div style=&amp;quot;margin:24px 0;&amp;quot;&amp;gt;
  &amp;lt;a href=&amp;quot;https://link.coupang.com/a/hgxRiuWt0C&amp;quot;
     target=&amp;quot;_blank&amp;quot;
     rel=&amp;quot;sponsored nofollow noopener&amp;quot;
     style=&amp;quot;
       display:block;
       width:100%;
       box-sizing:border-box;
       padding:17px 20px;
       background:#17212d;
       border:1px solid #6fe6c1;
       border-radius:12px;
       color:#ffffff;
       text-align:center;
       text-decoration:none;
       font-size:16px;
       font-weight:700;
     &amp;quot;&amp;gt;
    오리코 C타입 5IN1 멀티포트 허브 &amp;mdash; 쿠팡에서 현재 가격 확인하기 &amp;rarr;
  &amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;p style=&amp;quot;margin-top:40px; font-size:13px; color:#666; line-height:1.7;&amp;quot;&amp;gt;
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
&amp;lt;/p&amp;gt;&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;같이 읽으면 좋은 글&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;a href=&quot;https://nocklock.tistory.com/33&quot;&gt; 2026 개발자 노트북 추천 &amp;mdash; 입문용&amp;middot;실무용&amp;middot;휴대용으로 나눠봤다 &lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;a href=&quot;https://nocklock.tistory.com/34&quot;&gt; LG 그램 Pro 17 개발용으로 괜찮을까? AI&amp;middot;Ollama 때문에 RTX 5050까지 고민했다 &lt;/a&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;노트북을 고르면서 같이 보고 있는 것들&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노트북을 알아보다 보니 저장공간이나 포트처럼 노트북 사양만으로 끝나지 않는 부분도 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 직접 사용한 제품에 대한 후기는 아니고, 이번에 노트북을 준비하면서 같이 비교하고 있는 제품들이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;삼성전자 Portable SSD T7 Shield 1TB&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;512GB를 사용하다 저장공간이 부족해진다면 내장 SSD를 바로 늘리는 것 말고 외장 SSD를 사용하는 방법도 있다.&lt;/p&gt;
&lt;div style=&quot;margin: 24px 0;&quot;&gt;&lt;a style=&quot;display: block; width: 100%; box-sizing: border-box; padding: 17px 20px; background: #17212d; border: 1px solid #6fe6c1; border-radius: 12px; color: #ffffff; text-align: center; text-decoration: none; font-size: 16px; font-weight: bold;&quot; href=&quot;https://link.coupang.com/a/hgxSD1eJoa&quot; target=&quot;_blank&quot; rel=&quot;sponsored nofollow noopener&quot;&gt; 삼성 T7 Shield 1TB &amp;mdash; 쿠팡에서 현재 가격 확인하기 &amp;rarr; &lt;/a&gt;&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;USB-C 멀티허브&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;밖에서는 노트북 자체로 사용하더라도 집에서는 모니터나 USB 장치를 연결할 일이 많아 USB-C 허브도 같이 보고 있다.&lt;/p&gt;
&lt;div style=&quot;margin: 24px 0;&quot;&gt;&lt;a style=&quot;display: block; width: 100%; box-sizing: border-box; padding: 17px 20px; background: #17212d; border: 1px solid #6fe6c1; border-radius: 12px; color: #ffffff; text-align: center; text-decoration: none; font-size: 16px; font-weight: bold;&quot; href=&quot;https://link.coupang.com/a/hgxRiuWt0C&quot; target=&quot;_blank&quot; rel=&quot;sponsored nofollow noopener&quot;&gt; 오리코 C타입 5IN1 멀티포트 허브 &amp;mdash; 쿠팡에서 현재 가격 확인하기 &amp;rarr; &lt;/a&gt;&lt;/div&gt;
&lt;p style=&quot;margin-top: 40px; font-size: 13px; color: #666; line-height: 1.7;&quot; data-ke-size=&quot;size16&quot;&gt;이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.&lt;/p&gt;
&lt;/div&gt;</description>
      <category>개발 노트</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/38</guid>
      <comments>https://nocklock.tistory.com/38#entry38comment</comments>
      <pubDate>Wed, 23 Sep 2026 07:59:37 +0900</pubDate>
    </item>
    <item>
      <title>웹사이트는 내가 생각한 것보다 많은 걸 알고 있다</title>
      <link>https://nocklock.tistory.com/21</link>
      <description>&lt;p data-end=&quot;139&quot; data-start=&quot;112&quot; data-ke-size=&quot;size16&quot;&gt;얼마 전 어떤 사이트를 보다가 갑자기 궁금해졌다.&lt;/p&gt;
&lt;p data-end=&quot;190&quot; data-start=&quot;141&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 이 사이트에 들어오는 순간, 이 사이트는 나에 대해 어디까지 알 수 있을까?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;209&quot; data-start=&quot;192&quot; data-ke-size=&quot;size16&quot;&gt;IP 주소 정도는 알고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;249&quot; data-start=&quot;211&quot; data-ke-size=&quot;size16&quot;&gt;개발하면서 로그를 보다 보면 IP라는 게 그렇게 낯선 정보는 아니다.&lt;/p&gt;
&lt;p data-end=&quot;305&quot; data-start=&quot;251&quot; data-ke-size=&quot;size16&quot;&gt;그런데 막상 하나씩 찾아보기 시작하니까 생각보다 내가 브라우저를 통해 넘기고 있는 정보가 많았다.&lt;/p&gt;
&lt;p data-end=&quot;324&quot; data-start=&quot;307&quot; data-ke-size=&quot;size16&quot;&gt;그리고 또 이런 생각이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;344&quot; data-start=&quot;326&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역시 기술은 조금 무섭다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오전 12_24_56.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kE3qq/dJMb992g2tG/jKnlrkbAVDKRvvqMKXc1K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kE3qq/dJMb992g2tG/jKnlrkbAVDKRvvqMKXc1K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kE3qq/dJMb992g2tG/jKnlrkbAVDKRvvqMKXc1K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkE3qq%2FdJMb992g2tG%2FjKnlrkbAVDKRvvqMKXc1K1%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; alt=&quot;KnowAlot&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오전 12_24_56.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-end=&quot;349&quot; data-start=&quot;346&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;371&quot; data-start=&quot;351&quot; data-ke-size=&quot;size26&quot;&gt;접속만 했는데 이것까지 안다고?&lt;/h2&gt;
&lt;p data-end=&quot;396&quot; data-start=&quot;373&quot; data-ke-size=&quot;size16&quot;&gt;웹사이트에 접속하면 서버는 요청을 받는다.&lt;/p&gt;
&lt;p data-end=&quot;408&quot; data-start=&quot;398&quot; data-ke-size=&quot;size16&quot;&gt;그 요청에는 단순히&lt;/p&gt;
&lt;blockquote data-end=&quot;424&quot; data-start=&quot;410&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;424&quot; data-start=&quot;412&quot; data-ke-size=&quot;size16&quot;&gt;이 페이지 보여주세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;444&quot; data-start=&quot;426&quot; data-ke-size=&quot;size16&quot;&gt;라는 내용만 들어가는 게 아니다.&lt;/p&gt;
&lt;p data-end=&quot;537&quot; data-start=&quot;446&quot; data-ke-size=&quot;size16&quot;&gt;브라우저와 웹사이트의 구성에 따라 차이는 있지만, 사용자가 어떤 환경에서 접속하고 있는지 판단할 수 있는 여러 정보가 함께 전달되거나 브라우저에서 확인될 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;553&quot; data-start=&quot;539&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면 이런 것들이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;IP 주소
브라우저 종류
운영체제
화면 크기
언어 설정
시간대
접속한 페이지
이전에 방문한 페이지에 관한 일부 정보&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;650&quot; data-start=&quot;633&quot; data-ke-size=&quot;size16&quot;&gt;하나씩 보면 별거 없어 보인다.&lt;/p&gt;
&lt;p data-end=&quot;683&quot; data-start=&quot;652&quot; data-ke-size=&quot;size16&quot;&gt;내가 Chrome을 쓰는 게 뭐가 그렇게 중요한가 싶다.&lt;/p&gt;
&lt;p data-end=&quot;718&quot; data-start=&quot;685&quot; data-ke-size=&quot;size16&quot;&gt;화면 해상도를 안다고 해서 나를 찾을 수 있는 것도 아니다.&lt;/p&gt;
&lt;p data-end=&quot;755&quot; data-start=&quot;720&quot; data-ke-size=&quot;size16&quot;&gt;그런데 문제는 이런 정보가 &lt;b&gt;하나씩 모이기 시작했을 때&lt;/b&gt;다.&lt;/p&gt;
&lt;hr data-end=&quot;760&quot; data-start=&quot;757&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;781&quot; data-start=&quot;762&quot; data-ke-size=&quot;size26&quot;&gt;IP 주소는 내 집 주소일까?&lt;/h2&gt;
&lt;p data-end=&quot;807&quot; data-start=&quot;783&quot; data-ke-size=&quot;size16&quot;&gt;IP 이야기부터 보면 생각보다 오해가 많다.&lt;/p&gt;
&lt;p data-end=&quot;846&quot; data-start=&quot;809&quot; data-ke-size=&quot;size16&quot;&gt;IP 주소를 알면 바로 집 주소까지 알 수 있다고 생각하기도 한다.&lt;/p&gt;
&lt;p data-end=&quot;863&quot; data-start=&quot;848&quot; data-ke-size=&quot;size16&quot;&gt;그 정도로 단순하지는 않다.&lt;/p&gt;
&lt;p data-end=&quot;881&quot; data-start=&quot;865&quot; data-ke-size=&quot;size16&quot;&gt;IP만 가지고 일반 웹사이트가&lt;/p&gt;
&lt;blockquote data-end=&quot;903&quot; data-start=&quot;883&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;903&quot; data-start=&quot;885&quot; data-ke-size=&quot;size16&quot;&gt;서울시 어디 아파트 몇 동 몇 호&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;928&quot; data-start=&quot;905&quot; data-ke-size=&quot;size16&quot;&gt;같은 정보를 바로 알 수 있는 건 아니다.&lt;/p&gt;
&lt;p data-end=&quot;971&quot; data-start=&quot;930&quot; data-ke-size=&quot;size16&quot;&gt;보통은 인터넷 사업자나 대략적인 지역 수준의 정보와 연결해서 보는 정도다.&lt;/p&gt;
&lt;p data-end=&quot;1029&quot; data-start=&quot;973&quot; data-ke-size=&quot;size16&quot;&gt;게다가 모바일 네트워크나 회사 네트워크, VPN 같은 환경에서는 실제 위치와 다르게 보일 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;1035&quot; data-start=&quot;1031&quot; data-ke-size=&quot;size16&quot;&gt;그러니까&lt;/p&gt;
&lt;p data-end=&quot;1059&quot; data-start=&quot;1037&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;IP 주소 = 내 정확한 집 주소&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1075&quot; data-start=&quot;1061&quot; data-ke-size=&quot;size16&quot;&gt;라고 생각할 필요는 없다.&lt;/p&gt;
&lt;p data-end=&quot;1099&quot; data-start=&quot;1077&quot; data-ke-size=&quot;size16&quot;&gt;그렇다고 아무 정보도 아닌 것도 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1114&quot; data-start=&quot;1101&quot; data-ke-size=&quot;size16&quot;&gt;접속 기록을 구분하거나,&lt;/p&gt;
&lt;p data-end=&quot;1130&quot; data-start=&quot;1116&quot; data-ke-size=&quot;size16&quot;&gt;비정상적인 요청을 막거나,&lt;/p&gt;
&lt;p data-end=&quot;1165&quot; data-start=&quot;1132&quot; data-ke-size=&quot;size16&quot;&gt;대략적인 접속 지역을 판단하는 데는 충분히 사용할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1187&quot; data-start=&quot;1167&quot; data-ke-size=&quot;size16&quot;&gt;개발자 입장에서는 꽤 유용한 정보다.&lt;/p&gt;
&lt;p data-end=&quot;1206&quot; data-start=&quot;1189&quot; data-ke-size=&quot;size16&quot;&gt;사용자 입장에서는 조금 묘하다.&lt;/p&gt;
&lt;p data-end=&quot;1255&quot; data-start=&quot;1208&quot; data-ke-size=&quot;size16&quot;&gt;나는 그냥 페이지 하나를 열었을 뿐인데 서버에는 접속 흔적 하나가 남을 수 있으니까.&lt;/p&gt;
&lt;hr data-end=&quot;1260&quot; data-start=&quot;1257&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1284&quot; data-start=&quot;1262&quot; data-ke-size=&quot;size26&quot;&gt;브라우저도 생각보다 말을 많이 한다&lt;/h2&gt;
&lt;p data-end=&quot;1326&quot; data-start=&quot;1286&quot; data-ke-size=&quot;size16&quot;&gt;웹사이트는 내가 사용하는 브라우저나 기기 환경도 어느 정도 알 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1361&quot; data-start=&quot;1328&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 User-Agent라는 문자열을 많이 활용했다.&lt;/p&gt;
&lt;p data-end=&quot;1373&quot; data-start=&quot;1363&quot; data-ke-size=&quot;size16&quot;&gt;대략 이런 식이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;Chrome
Windows
64bit
...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1436&quot; data-start=&quot;1413&quot; data-ke-size=&quot;size16&quot;&gt;웹사이트 입장에서는 이런 정보가 필요하다.&lt;/p&gt;
&lt;p data-end=&quot;1474&quot; data-start=&quot;1438&quot; data-ke-size=&quot;size16&quot;&gt;모바일인지 PC인지에 따라 화면을 다르게 보여줘야 할 수도 있고,&lt;/p&gt;
&lt;p data-end=&quot;1508&quot; data-start=&quot;1476&quot; data-ke-size=&quot;size16&quot;&gt;특정 브라우저에서만 발생하는 오류를 찾아야 할 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;1547&quot; data-start=&quot;1510&quot; data-ke-size=&quot;size16&quot;&gt;웹 서비스를 만드는 개발자라면 오히려 이런 정보가 없으면 불편하다.&lt;/p&gt;
&lt;p data-end=&quot;1564&quot; data-start=&quot;1549&quot; data-ke-size=&quot;size16&quot;&gt;문제는 여기서 끝이 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1637&quot; data-start=&quot;1566&quot; data-ke-size=&quot;size16&quot;&gt;웹페이지에서 JavaScript를 사용하면 화면 크기나 언어, 시간대 등 브라우저가 제공하는 여러 환경 정보도 확인할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1645&quot; data-start=&quot;1639&quot; data-ke-size=&quot;size16&quot;&gt;다시 말해,&lt;/p&gt;
&lt;blockquote data-end=&quot;1672&quot; data-start=&quot;1647&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1672&quot; data-start=&quot;1649&quot; data-ke-size=&quot;size16&quot;&gt;IP만 숨기면 나는 아무것도 안 보이겠지.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1690&quot; data-start=&quot;1674&quot; data-ke-size=&quot;size16&quot;&gt;정도로 끝나는 문제는 아니다.&lt;/p&gt;
&lt;hr data-end=&quot;1695&quot; data-start=&quot;1692&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1723&quot; data-start=&quot;1697&quot; data-ke-size=&quot;size26&quot;&gt;하나씩은 평범한데, 합쳐지면 조금 달라진다&lt;/h2&gt;
&lt;p data-end=&quot;1751&quot; data-start=&quot;1725&quot; data-ke-size=&quot;size16&quot;&gt;여기서 브라우저 핑거프린팅이라는 개념이 나온다.&lt;/p&gt;
&lt;p data-end=&quot;1774&quot; data-start=&quot;1753&quot; data-ke-size=&quot;size16&quot;&gt;처음 이름을 봤을 때는 조금 무서웠다.&lt;/p&gt;
&lt;p data-end=&quot;1786&quot; data-start=&quot;1776&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;지문이라니.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1823&quot; data-start=&quot;1788&quot; data-ke-size=&quot;size16&quot;&gt;그런데 실제 개념은 물리적인 지문을 가져간다는 이야기는 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1866&quot; data-start=&quot;1825&quot; data-ke-size=&quot;size16&quot;&gt;브라우저가 가진 여러 특징을 조합해 같은 환경을 구별하려는 방식에 가깝다.&lt;/p&gt;
&lt;p data-end=&quot;1873&quot; data-start=&quot;1868&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;운영체제
브라우저 버전
화면 크기
언어
시간대
그래픽 환경
지원하는 기능&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1944&quot; data-start=&quot;1929&quot; data-ke-size=&quot;size16&quot;&gt;같은 정보가 있다고 해보자.&lt;/p&gt;
&lt;p data-end=&quot;1974&quot; data-start=&quot;1946&quot; data-ke-size=&quot;size16&quot;&gt;각각만 보면 수많은 사람이 같은 값을 가지고 있다.&lt;/p&gt;
&lt;p data-end=&quot;2016&quot; data-start=&quot;1976&quot; data-ke-size=&quot;size16&quot;&gt;하지만 여러 조건을 조합하면 상대적으로 드문 조합이 만들어질 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;2064&quot; data-start=&quot;2018&quot; data-ke-size=&quot;size16&quot;&gt;그래서 쿠키만 지운다고 해서 모든 추적 가능성이 완전히 사라진다고 말하기는 어렵다.&lt;/p&gt;
&lt;p data-end=&quot;2090&quot; data-start=&quot;2066&quot; data-ke-size=&quot;size16&quot;&gt;이 부분을 보면서 조금 재미있었던 게 있다.&lt;/p&gt;
&lt;p data-end=&quot;2109&quot; data-start=&quot;2092&quot; data-ke-size=&quot;size16&quot;&gt;나는 예전에는 개인정보라고 하면&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;이름
전화번호
주민등록번호
주소&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2155&quot; data-start=&quot;2142&quot; data-ke-size=&quot;size16&quot;&gt;같은 걸 먼저 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;2214&quot; data-start=&quot;2157&quot; data-ke-size=&quot;size16&quot;&gt;그런데 인터넷에서는 &lt;b&gt;직접적인 개인정보가 아니더라도 여러 정보가 조합되면서 의미가 생길 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;2219&quot; data-start=&quot;2216&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2240&quot; data-start=&quot;2221&quot; data-ke-size=&quot;size26&quot;&gt;시크릿 모드면 괜찮지 않을까?&lt;/h2&gt;
&lt;p data-end=&quot;2277&quot; data-start=&quot;2242&quot; data-ke-size=&quot;size16&quot;&gt;나도 한때 시크릿 모드를 켜면 꽤 익명에 가까워지는 줄 알았다.&lt;/p&gt;
&lt;p data-end=&quot;2302&quot; data-start=&quot;2279&quot; data-ke-size=&quot;size16&quot;&gt;그런데 시크릿 모드의 역할은 조금 다르다.&lt;/p&gt;
&lt;p data-end=&quot;2365&quot; data-start=&quot;2304&quot; data-ke-size=&quot;size16&quot;&gt;브라우저가 방문 기록이나 쿠키 같은 데이터를 &lt;b&gt;내 컴퓨터에 계속 남겨두지 않도록 하는 기능&lt;/b&gt;에 더 가깝다.&lt;/p&gt;
&lt;p data-end=&quot;2416&quot; data-start=&quot;2367&quot; data-ke-size=&quot;size16&quot;&gt;시크릿 모드로 접속한다고 해서 인터넷 사업자에게 내 접속이 갑자기 사라지는 것도 아니고,&lt;/p&gt;
&lt;p data-end=&quot;2449&quot; data-start=&quot;2418&quot; data-ke-size=&quot;size16&quot;&gt;접속한 웹사이트가 요청 자체를 받지 못하는 것도 아니다.&lt;/p&gt;
&lt;p data-end=&quot;2476&quot; data-start=&quot;2451&quot; data-ke-size=&quot;size16&quot;&gt;서버 입장에서는 여전히 접속한 사용자가 있다.&lt;/p&gt;
&lt;p data-end=&quot;2480&quot; data-start=&quot;2478&quot; data-ke-size=&quot;size16&quot;&gt;결국&lt;/p&gt;
&lt;blockquote data-end=&quot;2508&quot; data-start=&quot;2482&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2508&quot; data-start=&quot;2484&quot; data-ke-size=&quot;size16&quot;&gt;시크릿 모드 = 인터넷에서 보이지 않는 모드&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2516&quot; data-start=&quot;2510&quot; data-ke-size=&quot;size16&quot;&gt;는 아니다.&lt;/p&gt;
&lt;p data-end=&quot;2544&quot; data-start=&quot;2518&quot; data-ke-size=&quot;size16&quot;&gt;이걸 처음 제대로 이해했을 때도 조금 당황했다.&lt;/p&gt;
&lt;p data-end=&quot;2578&quot; data-start=&quot;2546&quot; data-ke-size=&quot;size16&quot;&gt;이름 때문에 나도 모르게 기대를 너무 많이 했던 것 같다.&lt;/p&gt;
&lt;hr data-end=&quot;2583&quot; data-start=&quot;2580&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2619&quot; data-start=&quot;2585&quot; data-ke-size=&quot;size26&quot;&gt;그렇다고 웹사이트가 몰래 나를 감시한다는 이야기는 아니다&lt;/h2&gt;
&lt;p data-end=&quot;2649&quot; data-start=&quot;2621&quot; data-ke-size=&quot;size16&quot;&gt;여기까지 쓰면 인터넷이 꽤 무서운 공간처럼 보인다.&lt;/p&gt;
&lt;p data-end=&quot;2672&quot; data-start=&quot;2651&quot; data-ke-size=&quot;size16&quot;&gt;그런데 나는 그렇게 생각하지는 않는다.&lt;/p&gt;
&lt;p data-end=&quot;2712&quot; data-start=&quot;2674&quot; data-ke-size=&quot;size16&quot;&gt;개발자 입장에서 보면 이런 정보가 왜 필요한지 이해되는 부분도 많다.&lt;/p&gt;
&lt;p data-end=&quot;2724&quot; data-start=&quot;2714&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 사용자가&lt;/p&gt;
&lt;blockquote data-end=&quot;2742&quot; data-start=&quot;2726&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2742&quot; data-start=&quot;2728&quot; data-ke-size=&quot;size16&quot;&gt;페이지가 이상하게 보여요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2757&quot; data-start=&quot;2744&quot; data-ke-size=&quot;size16&quot;&gt;라고 문의했다고 해보자.&lt;/p&gt;
&lt;p data-end=&quot;2769&quot; data-start=&quot;2759&quot; data-ke-size=&quot;size16&quot;&gt;개발자는 궁금하다.&lt;/p&gt;
&lt;p data-end=&quot;2789&quot; data-start=&quot;2771&quot; data-ke-size=&quot;size16&quot;&gt;Chrome에서만 발생하는 건지,&lt;/p&gt;
&lt;p data-end=&quot;2806&quot; data-start=&quot;2791&quot; data-ke-size=&quot;size16&quot;&gt;모바일에서만 발생하는 건지,&lt;/p&gt;
&lt;p data-end=&quot;2821&quot; data-start=&quot;2808&quot; data-ke-size=&quot;size16&quot;&gt;특정 운영체제 문제인지,&lt;/p&gt;
&lt;p data-end=&quot;2835&quot; data-start=&quot;2823&quot; data-ke-size=&quot;size16&quot;&gt;특정 버전의 문제인지.&lt;/p&gt;
&lt;p data-end=&quot;2866&quot; data-start=&quot;2837&quot; data-ke-size=&quot;size16&quot;&gt;이런 정보가 있으면 문제를 훨씬 빨리 찾을 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2883&quot; data-start=&quot;2868&quot; data-ke-size=&quot;size16&quot;&gt;서비스 이용 통계를 보거나,&lt;/p&gt;
&lt;p data-end=&quot;2920&quot; data-start=&quot;2885&quot; data-ke-size=&quot;size16&quot;&gt;해킹이나 비정상적인 요청을 막기 위해서도 일부 정보는 필요하다.&lt;/p&gt;
&lt;p data-end=&quot;2926&quot; data-start=&quot;2922&quot; data-ke-size=&quot;size16&quot;&gt;그러니까&lt;/p&gt;
&lt;p data-end=&quot;2949&quot; data-start=&quot;2928&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정보를 수집한다 = 나쁜 사이트&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2967&quot; data-start=&quot;2951&quot; data-ke-size=&quot;size16&quot;&gt;라고 단순하게 볼 수는 없다.&lt;/p&gt;
&lt;p data-end=&quot;3016&quot; data-start=&quot;2969&quot; data-ke-size=&quot;size16&quot;&gt;중요한 건 결국 어떤 정보를 왜 수집하고, 어떻게 사용하는가에 더 가깝다고 생각한다.&lt;/p&gt;
&lt;hr data-end=&quot;3021&quot; data-start=&quot;3018&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3050&quot; data-start=&quot;3023&quot; data-ke-size=&quot;size26&quot;&gt;내가 조금 무섭다고 느낀 건 다른 부분이었다&lt;/h2&gt;
&lt;p data-end=&quot;3088&quot; data-start=&quot;3052&quot; data-ke-size=&quot;size16&quot;&gt;웹사이트가 내 화면 크기를 안다는 사실 자체가 무서운 건 아니다.&lt;/p&gt;
&lt;p data-end=&quot;3125&quot; data-start=&quot;3090&quot; data-ke-size=&quot;size16&quot;&gt;IP를 안다는 것도 인터넷 구조를 생각하면 이상한 일은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;3143&quot; data-start=&quot;3127&quot; data-ke-size=&quot;size16&quot;&gt;내가 조금 무섭다고 느꼈던 건&lt;/p&gt;
&lt;p data-end=&quot;3189&quot; data-start=&quot;3145&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;나는 이런 정보가 오가는지도 모르고 인터넷을 사용하고 있었다는 것&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p data-end=&quot;3202&quot; data-start=&quot;3191&quot; data-ke-size=&quot;size16&quot;&gt;그냥 사이트를 열고,&lt;/p&gt;
&lt;p data-end=&quot;3210&quot; data-start=&quot;3204&quot; data-ke-size=&quot;size16&quot;&gt;로그인하고,&lt;/p&gt;
&lt;p data-end=&quot;3220&quot; data-start=&quot;3212&quot; data-ke-size=&quot;size16&quot;&gt;사진을 올리고,&lt;/p&gt;
&lt;p data-end=&quot;3230&quot; data-start=&quot;3222&quot; data-ke-size=&quot;size16&quot;&gt;버튼을 누른다.&lt;/p&gt;
&lt;p data-end=&quot;3249&quot; data-start=&quot;3232&quot; data-ke-size=&quot;size16&quot;&gt;사용자 입장에서는 그게 전부다.&lt;/p&gt;
&lt;p data-end=&quot;3295&quot; data-start=&quot;3251&quot; data-ke-size=&quot;size16&quot;&gt;그 뒤에서 어떤 정보가 전달되고 어떤 기술이 동작하는지는 대부분 보이지 않는다.&lt;/p&gt;
&lt;p data-end=&quot;3359&quot; data-start=&quot;3297&quot; data-ke-size=&quot;size16&quot;&gt;개발을 다시 공부하면서 이런 부분을 하나씩 들여다보게 되니까 예전에는 그냥 지나쳤던 것들이 계속 눈에 들어온다.&lt;/p&gt;
&lt;p data-end=&quot;3392&quot; data-start=&quot;3361&quot; data-ke-size=&quot;size16&quot;&gt;사진 한 장에도 내가 생각하지 못한 정보가 들어 있었고,&lt;/p&gt;
&lt;p data-end=&quot;3423&quot; data-start=&quot;3394&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 브라우저도 생각보다 많은 말을 하고 있었다.&lt;/p&gt;
&lt;hr data-end=&quot;3428&quot; data-start=&quot;3425&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3449&quot; data-start=&quot;3430&quot; data-ke-size=&quot;size26&quot;&gt;그래도 인터넷은 계속 쓸 거다&lt;/h2&gt;
&lt;p data-end=&quot;3480&quot; data-start=&quot;3451&quot; data-ke-size=&quot;size16&quot;&gt;이런 걸 알았다고 갑자기 인터넷을 끊을 생각은 없다.&lt;/p&gt;
&lt;p data-end=&quot;3521&quot; data-start=&quot;3482&quot; data-ke-size=&quot;size16&quot;&gt;VPN을 항상 켜고 모든 쿠키를 차단하면서 살아갈 생각도 아직은 없다.&lt;/p&gt;
&lt;p data-end=&quot;3540&quot; data-start=&quot;3523&quot; data-ke-size=&quot;size16&quot;&gt;그렇게 하면 불편한 것도 많다.&lt;/p&gt;
&lt;p data-end=&quot;3561&quot; data-start=&quot;3542&quot; data-ke-size=&quot;size16&quot;&gt;다만 예전과 조금 달라진 건 있다.&lt;/p&gt;
&lt;p data-end=&quot;3598&quot; data-start=&quot;3563&quot; data-ke-size=&quot;size16&quot;&gt;사이트에서 이상하게 많은 권한을 요구하면 한 번 더 생각해보고,&lt;/p&gt;
&lt;p data-end=&quot;3617&quot; data-start=&quot;3600&quot; data-ke-size=&quot;size16&quot;&gt;사용하지 않는 계정은 정리하고,&lt;/p&gt;
&lt;p data-end=&quot;3642&quot; data-start=&quot;3619&quot; data-ke-size=&quot;size16&quot;&gt;중요한 서비스의 비밀번호는 따로 관리하고,&lt;/p&gt;
&lt;p data-end=&quot;3676&quot; data-start=&quot;3644&quot; data-ke-size=&quot;size16&quot;&gt;무심코 넘겼던 개인정보 관련 설정도 가끔 들여다보게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;3697&quot; data-start=&quot;3678&quot; data-ke-size=&quot;size16&quot;&gt;완벽하게 숨는 방법을 찾는 것보다,&lt;/p&gt;
&lt;p data-end=&quot;3730&quot; data-start=&quot;3699&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 어떤 정보를 넘기고 있는지는 알고 쓰는 것.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3756&quot; data-start=&quot;3732&quot; data-ke-size=&quot;size16&quot;&gt;지금은 그 정도면 충분하지 않을까 생각한다.&lt;/p&gt;
&lt;p data-end=&quot;3769&quot; data-start=&quot;3758&quot; data-ke-size=&quot;size16&quot;&gt;기술은 정말 편하다.&lt;/p&gt;
&lt;p data-end=&quot;3787&quot; data-start=&quot;3771&quot; data-ke-size=&quot;size16&quot;&gt;그리고 알면 알수록 신기하다.&lt;/p&gt;
&lt;p data-end=&quot;3796&quot; data-start=&quot;3789&quot; data-ke-size=&quot;size16&quot;&gt;그런데 가끔,&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;3809&quot; data-start=&quot;3798&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;조금 무섭다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>기술이 조금 무섭다</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/21</guid>
      <comments>https://nocklock.tistory.com/21#entry21comment</comments>
      <pubDate>Tue, 22 Sep 2026 20:25:31 +0900</pubDate>
    </item>
    <item>
      <title>LG 그램 Pro 17 개발용으로 괜찮을까? AI&amp;middot;Ollama 때문에 RTX 5050까지 고민했다</title>
      <link>https://nocklock.tistory.com/34</link>
      <description>&lt;div id=&quot;code_1790040219571&quot; data-ke-type=&quot;html&quot; data-source=&quot;&amp;lt;p style=&amp;quot;font-size:14px; color:#666666; line-height:1.6; margin:0 0 24px 0;&amp;quot;&amp;gt;
※ 이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
&amp;lt;/p&amp;gt;&quot;&gt;
&lt;p style=&quot;font-size: 14px; color: #666666; line-height: 1.6; margin: 0 0 24px 0;&quot; data-ke-size=&quot;size16&quot;&gt;※ 이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;p data-end=&quot;551&quot; data-start=&quot;536&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;551&quot; data-start=&quot;536&quot; data-ke-size=&quot;size16&quot;&gt;노트북을 하나 사려고 했다.&lt;/p&gt;
&lt;p data-end=&quot;569&quot; data-start=&quot;553&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 기준이 꽤 단순했다.&lt;/p&gt;
&lt;p data-end=&quot;592&quot; data-start=&quot;571&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;화면이 크고, 가벼우면 좋겠다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;592&quot; data-start=&quot;571&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;637&quot; data-start=&quot;594&quot; data-ke-size=&quot;size16&quot;&gt;예전에 성능이 괜찮은 게이밍 노트북을 가지고 있었는데 잘 들고 다니지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;637&quot; data-start=&quot;594&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;644&quot; data-start=&quot;639&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;무거웠다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;644&quot; data-start=&quot;639&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;691&quot; data-start=&quot;646&quot; data-ke-size=&quot;size16&quot;&gt;결국 집에서는 데스크톱을 쓰고, 노트북은 책상 한쪽에 놓여 있는 시간이 길어졌다.&lt;/p&gt;
&lt;p data-end=&quot;710&quot; data-start=&quot;693&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번에는 생각을 바꿨다.&lt;/p&gt;
&lt;p data-end=&quot;763&quot; data-start=&quot;712&quot; data-ke-size=&quot;size16&quot;&gt;성능표에서 숫자가 가장 높은 노트북보다 &lt;b&gt;실제로 내가 들고 다닐 노트북을 사기로 했다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;801&quot; data-start=&quot;765&quot; data-ke-size=&quot;size16&quot;&gt;그렇게 찾아보다 가장 먼저 눈에 들어온 게 LG 그램 17이었다.&lt;/p&gt;
&lt;p data-end=&quot;827&quot; data-start=&quot;803&quot; data-ke-size=&quot;size16&quot;&gt;17인치라 화면은 크고, 그램답게 가벼웠다.&lt;/p&gt;
&lt;p data-end=&quot;847&quot; data-start=&quot;829&quot; data-ke-size=&quot;size16&quot;&gt;내가 원하던 조건과 거의 맞았다.&lt;/p&gt;
&lt;p data-end=&quot;866&quot; data-start=&quot;849&quot; data-ke-size=&quot;size16&quot;&gt;그런데 한 가지 문제가 생겼다.&lt;/p&gt;
&lt;p data-end=&quot;866&quot; data-start=&quot;849&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;891&quot; data-start=&quot;868&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;요즘 내가 AI를 건드리고 있었다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 22일 오전 10_00_10.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEc2RH/dJMcajp7359/p1M8w4NkZ3oTUXlTAPt38k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEc2RH/dJMcajp7359/p1M8w4NkZ3oTUXlTAPt38k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEc2RH/dJMcajp7359/p1M8w4NkZ3oTUXlTAPt38k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEc2RH%2FdJMcajp7359%2Fp1M8w4NkZ3oTUXlTAPt38k%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; alt=&quot;problem is AI&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 22일 오전 10_00_10.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-end=&quot;896&quot; data-start=&quot;893&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;932&quot; data-start=&quot;898&quot; data-section-id=&quot;58xt4z&quot; data-ke-size=&quot;size23&quot;&gt;ChatGPT를 쓰는 것과 AI를 직접 돌리는 건 달랐다&lt;/h3&gt;
&lt;p data-end=&quot;957&quot; data-start=&quot;934&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 이 차이를 크게 생각하지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;1003&quot; data-start=&quot;959&quot; data-ke-size=&quot;size16&quot;&gt;ChatGPT나 Claude를 사용하는 건 노트북 성능이 그렇게 중요하지 않다.&lt;/p&gt;
&lt;p data-end=&quot;1047&quot; data-start=&quot;1005&quot; data-ke-size=&quot;size16&quot;&gt;AI 연산 자체는 내 노트북이 아니라 서비스 회사의 서버에서 하기 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;1091&quot; data-start=&quot;1049&quot; data-ke-size=&quot;size16&quot;&gt;개발할 때 OpenAI나 Gemini 같은 API를 사용하는 것도 비슷하다.&lt;/p&gt;
&lt;p data-end=&quot;1160&quot; data-start=&quot;1093&quot; data-ke-size=&quot;size16&quot;&gt;그런데 최근 보안렌즈 프로젝트를 만들면서 Ollama를 설치했고, Gemma 같은 모델을 내 컴퓨터에서 직접 실행해봤다.&lt;/p&gt;
&lt;p data-end=&quot;1176&quot; data-start=&quot;1162&quot; data-ke-size=&quot;size16&quot;&gt;여기서 이야기가 달라졌다.&lt;/p&gt;
&lt;p data-end=&quot;1208&quot; data-start=&quot;1178&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;로컬 LLM은 내 컴퓨터가 직접 계산해야 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1253&quot; data-start=&quot;1210&quot; data-ke-size=&quot;size16&quot;&gt;그때부터 노트북 사양표에서 예전에는 크게 보지 않던 단어들이 보이기 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;1259&quot; data-start=&quot;1255&quot; data-ke-size=&quot;size16&quot;&gt;GPU.&lt;/p&gt;
&lt;p data-end=&quot;1266&quot; data-start=&quot;1261&quot; data-ke-size=&quot;size16&quot;&gt;VRAM.&lt;/p&gt;
&lt;p data-end=&quot;1272&quot; data-start=&quot;1268&quot; data-ke-size=&quot;size16&quot;&gt;NPU.&lt;/p&gt;
&lt;p data-end=&quot;1279&quot; data-start=&quot;1274&quot; data-ke-size=&quot;size16&quot;&gt;CUDA.&lt;/p&gt;
&lt;p data-end=&quot;1314&quot; data-start=&quot;1281&quot; data-ke-size=&quot;size16&quot;&gt;노트북을 사려고 했는데 어느 순간 AI 공부를 하고 있었다.&lt;/p&gt;
&lt;hr data-end=&quot;1319&quot; data-start=&quot;1316&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1352&quot; data-start=&quot;1321&quot; data-section-id=&quot;xtntvk&quot; data-ke-size=&quot;size23&quot;&gt;AI 노트북이면 로컬 AI도 잘 돌아가는 줄 알았다&lt;/h3&gt;
&lt;p data-end=&quot;1399&quot; data-start=&quot;1354&quot; data-ke-size=&quot;size16&quot;&gt;요즘 노트북에는 'AI PC', 'AI 노트북'이라는 말이 정말 많이 붙어 있다.&lt;/p&gt;
&lt;p data-end=&quot;1446&quot; data-start=&quot;1401&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 NPU가 있으면 Ollama 같은 로컬 AI도 잘 돌아가는 건가 싶었다.&lt;/p&gt;
&lt;p data-end=&quot;1465&quot; data-start=&quot;1448&quot; data-ke-size=&quot;size16&quot;&gt;그런데 알아볼수록 조금 달랐다.&lt;/p&gt;
&lt;p data-end=&quot;1574&quot; data-start=&quot;1467&quot; data-ke-size=&quot;size16&quot;&gt;NPU는 저전력으로 AI 기능을 처리하는 데 유용하지만, &lt;b&gt;내가 Ollama로 모델을 직접 돌리고 CUDA 기반 AI 개발까지 해보고 싶다면 NVIDIA GPU가 훨씬 중요한 선택지&lt;/b&gt;였다.&lt;/p&gt;
&lt;p data-end=&quot;1606&quot; data-start=&quot;1576&quot; data-ke-size=&quot;size16&quot;&gt;여기서 내가 처음 생각했던 일반 그램과 고민이 생겼다.&lt;/p&gt;
&lt;p data-end=&quot;1627&quot; data-start=&quot;1608&quot; data-ke-size=&quot;size16&quot;&gt;일반 그램은 개발용으로는 충분했다.&lt;/p&gt;
&lt;p data-end=&quot;1721&quot; data-start=&quot;1629&quot; data-ke-size=&quot;size16&quot;&gt;IntelliJ를 띄우고 Spring Boot를 실행하고, Docker나 DB를 사용하고, ChatGPT와 Claude를 열어놓는 것까지는 크게 문제가 없어 보였다.&lt;/p&gt;
&lt;p data-end=&quot;1746&quot; data-start=&quot;1723&quot; data-ke-size=&quot;size16&quot;&gt;그런데 로컬 LLM까지 생각하면 아쉬웠다.&lt;/p&gt;
&lt;hr data-end=&quot;1751&quot; data-start=&quot;1748&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1786&quot; data-start=&quot;1753&quot; data-section-id=&quot;114aa60&quot; data-ke-size=&quot;size23&quot;&gt;내 데스크톱이 좋았다면 그냥 일반 그램을 샀을 것 같다&lt;/h3&gt;
&lt;p data-end=&quot;1828&quot; data-start=&quot;1788&quot; data-ke-size=&quot;size16&quot;&gt;사실 집에 좋은 AI용 데스크톱이 있었다면 고민이 거의 끝났을 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;1849&quot; data-start=&quot;1830&quot; data-ke-size=&quot;size16&quot;&gt;노트북은 가벼운 일반 그램을 사고,&lt;/p&gt;
&lt;p data-end=&quot;1881&quot; data-start=&quot;1851&quot; data-ke-size=&quot;size16&quot;&gt;집에서는 데스크톱 GPU로 Ollama를 돌리면 된다.&lt;/p&gt;
&lt;p data-end=&quot;1897&quot; data-start=&quot;1883&quot; data-ke-size=&quot;size16&quot;&gt;그런데 내 현재 데스크톱은&lt;/p&gt;
&lt;p data-end=&quot;1925&quot; data-start=&quot;1899&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RAM 16GB + GTX 1050 Ti&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1929&quot; data-start=&quot;1927&quot; data-ke-size=&quot;size16&quot;&gt;다.&lt;/p&gt;
&lt;p data-end=&quot;2004&quot; data-start=&quot;1931&quot; data-ke-size=&quot;size16&quot;&gt;아직 개발하고 일반적으로 사용하는 데 큰 문제는 없지만, 지금 기준으로 로컬 AI를 제대로 실험하기 좋은 머신이라고 하기는 어렵다.&lt;/p&gt;
&lt;p data-end=&quot;2033&quot; data-start=&quot;2006&quot; data-ke-size=&quot;size16&quot;&gt;그러면 일반 그램을 사는 순간 이런 상황이 된다.&lt;/p&gt;
&lt;blockquote data-end=&quot;2078&quot; data-start=&quot;2035&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2078&quot; data-start=&quot;2037&quot; data-ke-size=&quot;size16&quot;&gt;데스크톱도 로컬 AI에는 아쉽고&lt;br /&gt;새 노트북도 로컬 AI에는 아쉽다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2128&quot; data-start=&quot;2080&quot; data-ke-size=&quot;size16&quot;&gt;컴퓨터는 두 대인데 내가 앞으로 공부하고 싶은 환경은 어느 쪽에도 제대로 없는 셈이다.&lt;/p&gt;
&lt;p data-end=&quot;2146&quot; data-start=&quot;2130&quot; data-ke-size=&quot;size16&quot;&gt;그래서 그램을 다시 찾아봤다.&lt;/p&gt;
&lt;p data-end=&quot;2189&quot; data-start=&quot;2148&quot; data-ke-size=&quot;size16&quot;&gt;그러다 발견한 게 &lt;b&gt;RTX 5050이 들어간 그램 Pro 17&lt;/b&gt;이었다.&lt;/p&gt;
&lt;hr data-end=&quot;2194&quot; data-start=&quot;2191&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2220&quot; data-start=&quot;2196&quot; data-section-id=&quot;1ktczts&quot; data-ke-size=&quot;size23&quot;&gt;그램인데 RTX 5050이 들어가 있었다&lt;/h3&gt;
&lt;p data-end=&quot;2240&quot; data-start=&quot;2222&quot; data-ke-size=&quot;size16&quot;&gt;내가 최종적으로 보고 있는 모델은&lt;/p&gt;
&lt;p data-end=&quot;2276&quot; data-start=&quot;2242&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LG gram Pro 17 17Z90TR-ED7HK&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-end=&quot;2286&quot; data-start=&quot;2278&quot; data-ke-size=&quot;size16&quot;&gt;사양은 이렇다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;항목사양
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2533&quot; data-start=&quot;2288&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;2533&quot; data-start=&quot;2310&quot;&gt;
&lt;tr data-end=&quot;2348&quot; data-start=&quot;2310&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2315&quot; data-start=&quot;2310&quot;&gt;화면&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2348&quot; data-start=&quot;2315&quot;&gt;17인치급(43.1cm) WQXGA 2560&amp;times;1600&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2382&quot; data-start=&quot;2349&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2355&quot; data-start=&quot;2349&quot;&gt;CPU&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2382&quot; data-start=&quot;2355&quot;&gt;Intel Core Ultra 7 255H&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2409&quot; data-start=&quot;2383&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2389&quot; data-start=&quot;2383&quot;&gt;RAM&lt;/td&gt;
&lt;td data-end=&quot;2409&quot; data-start=&quot;2389&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;32GB LPDDR5x&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2447&quot; data-start=&quot;2410&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2416&quot; data-start=&quot;2410&quot;&gt;GPU&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2447&quot; data-start=&quot;2416&quot;&gt;&lt;b&gt;NVIDIA GeForce RTX 5050&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2475&quot; data-start=&quot;2448&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2458&quot; data-start=&quot;2448&quot;&gt;그래픽 메모리&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2475&quot; data-start=&quot;2458&quot;&gt;&lt;b&gt;GDDR7 8GB&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2510&quot; data-start=&quot;2476&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2482&quot; data-start=&quot;2476&quot;&gt;SSD&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2510&quot; data-start=&quot;2482&quot;&gt;&lt;b&gt;1TB NVMe + 추가 SSD 슬롯&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2533&quot; data-start=&quot;2511&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2516&quot; data-start=&quot;2511&quot;&gt;무게&lt;/td&gt;
&lt;td data-end=&quot;2533&quot; data-start=&quot;2516&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;약 1.479kg&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2535&quot; data-ke-size=&quot;size16&quot;&gt;LG 공식 사양에서도 Ultra 7 255H, RAM 32GB, RTX 5050 8GB, 1TB SSD와 추가 SSD 슬롯, 약 1.479kg으로 확인된다. &lt;span data-content-reference-end=&quot;2681&quot; data-content-reference-start=&quot;2643&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2684&quot; data-start=&quot;2662&quot; data-ke-size=&quot;size16&quot;&gt;이 사양을 보고 다시 고민하기 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;2723&quot; data-start=&quot;2686&quot; data-ke-size=&quot;size16&quot;&gt;17인치에 외장 GPU까지 들어갔는데 무게가 약 1.48kg이었다.&lt;/p&gt;
&lt;p data-end=&quot;2731&quot; data-start=&quot;2725&quot; data-ke-size=&quot;size16&quot;&gt;내가 원했던&lt;/p&gt;
&lt;p data-end=&quot;2747&quot; data-start=&quot;2733&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;큰 화면 + 휴대성&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2764&quot; data-start=&quot;2749&quot; data-ke-size=&quot;size16&quot;&gt;을 크게 포기하지 않으면서,&lt;/p&gt;
&lt;p data-end=&quot;2780&quot; data-start=&quot;2766&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AI 개발용 GPU&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2795&quot; data-start=&quot;2782&quot; data-ke-size=&quot;size16&quot;&gt;까지 가져갈 수 있었다.&lt;/p&gt;
&lt;p data-end=&quot;2809&quot; data-start=&quot;2797&quot; data-ke-size=&quot;size16&quot;&gt;물론 가격도 올라갔다.&lt;/p&gt;
&lt;hr data-end=&quot;2814&quot; data-start=&quot;2811&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2840&quot; data-start=&quot;2816&quot; data-section-id=&quot;1beiaeo&quot; data-ke-size=&quot;size23&quot;&gt;Ultra 5와 Ultra 7도 고민했다&lt;/h3&gt;
&lt;p data-end=&quot;2878&quot; data-start=&quot;2842&quot; data-ke-size=&quot;size16&quot;&gt;RTX 5050 모델에도 Ultra 5와 Ultra 7이 있었다.&lt;/p&gt;
&lt;p data-end=&quot;2907&quot; data-start=&quot;2880&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 Ultra 5면 충분하지 않을까 싶었다.&lt;/p&gt;
&lt;p data-end=&quot;2935&quot; data-start=&quot;2909&quot; data-ke-size=&quot;size16&quot;&gt;사실 내 작업만 놓고 보면 틀린 생각은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;3099&quot; data-start=&quot;2937&quot; data-ke-size=&quot;size16&quot;&gt;Ultra 5 225H도 14코어이고 최대 4.9GHz까지 동작한다. Ultra 7 255H는 16코어, 최대 5.1GHz이고 캐시도 18MB에서 24MB로 늘어난다. 반면 두 CPU의 NPU 성능은 모두 13 TOPS다. &lt;span data-content-reference-end=&quot;3125&quot; data-content-reference-start=&quot;3083&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3117&quot; data-start=&quot;3101&quot; data-ke-size=&quot;size16&quot;&gt;쉽게 말하면 이런 느낌이었다.&lt;/p&gt;
&lt;p data-end=&quot;3130&quot; data-start=&quot;3119&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Ultra 5&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-end=&quot;3148&quot; data-start=&quot;3132&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;3148&quot; data-start=&quot;3134&quot; data-ke-size=&quot;size16&quot;&gt;이미 충분히 빠른 CPU.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;3161&quot; data-start=&quot;3150&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Ultra 7&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-end=&quot;3200&quot; data-start=&quot;3163&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;3200&quot; data-start=&quot;3165&quot; data-ke-size=&quot;size16&quot;&gt;여러 개발 작업을 동시에 돌릴 때 조금 더 여유가 있는 CPU.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;3259&quot; data-start=&quot;3202&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3259&quot; data-start=&quot;3202&quot; data-ke-size=&quot;size16&quot;&gt;Ollama 성능만 생각한다면 둘의 차이보다 RTX 5050과 8GB VRAM이 훨씬 중요하다고 봤다.&lt;/p&gt;
&lt;p data-end=&quot;3289&quot; data-start=&quot;3261&quot; data-ke-size=&quot;size16&quot;&gt;그래서 처음에는 Ultra 5 쪽으로 마음이 갔다.&lt;/p&gt;
&lt;hr data-end=&quot;3294&quot; data-start=&quot;3291&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3331&quot; data-start=&quot;3296&quot; data-section-id=&quot;xa14ds&quot; data-ke-size=&quot;size23&quot;&gt;그런데 1TB로 조건을 맞추니 가격 차이가 생각보다 작았다&lt;/h3&gt;
&lt;p data-end=&quot;3352&quot; data-start=&quot;3333&quot; data-ke-size=&quot;size16&quot;&gt;여기서 생각이 한 번 더 바뀌었다.&lt;/p&gt;
&lt;p data-end=&quot;3401&quot; data-start=&quot;3354&quot; data-ke-size=&quot;size16&quot;&gt;Ultra 5 모델은 기본 512GB 구성이 많았고 Ultra 7 모델은 1TB였다.&lt;/p&gt;
&lt;p data-end=&quot;3424&quot; data-start=&quot;3403&quot; data-ke-size=&quot;size16&quot;&gt;개발만 하면 512GB도 쓸 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;3503&quot; data-start=&quot;3426&quot; data-ke-size=&quot;size16&quot;&gt;그런데 앞으로 Docker 이미지, WSL, 프로젝트, SDK에 Ollama 모델까지 쌓일 걸 생각하니 이번에는 1TB로 시작하고 싶었다.&lt;/p&gt;
&lt;p data-end=&quot;3541&quot; data-start=&quot;3505&quot; data-ke-size=&quot;size16&quot;&gt;그래서 두 모델을 &lt;b&gt;1TB 조건으로 맞춰서&lt;/b&gt; 가격을 찾아봤다.&lt;/p&gt;
&lt;p data-end=&quot;3563&quot; data-start=&quot;3543&quot; data-ke-size=&quot;size16&quot;&gt;2026년 9월 22일 확인 기준 유통가로는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3630&quot; data-start=&quot;3565&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3597&quot; data-start=&quot;3565&quot; data-section-id=&quot;vz20dv&quot;&gt;Ultra 5 / 1TB 구성: 약 &lt;b&gt;358만 원&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;3630&quot; data-start=&quot;3598&quot; data-section-id=&quot;6jkr5l&quot;&gt;Ultra 7 / 1TB 구성: 약 &lt;b&gt;372만 원&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3655&quot; data-start=&quot;3632&quot; data-ke-size=&quot;size16&quot;&gt;정도로 차이가 약 &lt;b&gt;14만 원&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p data-end=&quot;3777&quot; data-start=&quot;3657&quot; data-ke-size=&quot;size16&quot;&gt;판매처와 할인에 따라 가격은 계속 달라지지만, 이 정도 차이라면 몇 년 사용할 노트북에서 Ultra 5를 선택해 아낄 이유가 크지 않다고 판단했다. &lt;span data-content-reference-end=&quot;3808&quot; data-content-reference-start=&quot;3766&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3832&quot; data-start=&quot;3779&quot; data-ke-size=&quot;size16&quot;&gt;그래서 현재 내 선택은 &lt;b&gt;Ultra 7 / 32GB / 1TB / RTX 5050&lt;/b&gt; 쪽이다.&lt;/p&gt;
&lt;hr data-end=&quot;3837&quot; data-start=&quot;3834&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3873&quot; data-start=&quot;3839&quot; data-section-id=&quot;rxku39&quot; data-ke-size=&quot;size23&quot;&gt;RTX 5050이면 로컬 LLM을 마음껏 돌릴 수 있을까?&lt;/h3&gt;
&lt;p data-end=&quot;3882&quot; data-start=&quot;3875&quot; data-ke-size=&quot;size16&quot;&gt;그건 아니다.&lt;/p&gt;
&lt;p data-end=&quot;3906&quot; data-start=&quot;3884&quot; data-ke-size=&quot;size16&quot;&gt;여기서 기대치를 잘 잡을 필요가 있었다.&lt;/p&gt;
&lt;p data-end=&quot;3978&quot; data-start=&quot;3908&quot; data-ke-size=&quot;size16&quot;&gt;RTX 5050에는 전용 그래픽 메모리 8GB가 들어간다. &lt;span data-content-reference-end=&quot;3994&quot; data-content-reference-start=&quot;3972&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;4071&quot; data-start=&quot;3980&quot; data-ke-size=&quot;size16&quot;&gt;일반 내장그래픽 노트북보다 Ollama와 CUDA 기반 AI 실험에는 훨씬 유리하지만, 이걸 대형 LLM을 마음껏 돌리는 AI 워크스테이션이라고 생각하면 안 된다.&lt;/p&gt;
&lt;p data-end=&quot;4086&quot; data-start=&quot;4073&quot; data-ke-size=&quot;size16&quot;&gt;내 목적은 조금 다르다.&lt;/p&gt;
&lt;p data-end=&quot;4126&quot; data-start=&quot;4088&quot; data-ke-size=&quot;size16&quot;&gt;나는 이 노트북 한 대에서 거대한 AI 모델을 운영하려는 게 아니다.&lt;/p&gt;
&lt;p data-end=&quot;4136&quot; data-start=&quot;4128&quot; data-ke-size=&quot;size16&quot;&gt;내가 원하는 건&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4251&quot; data-start=&quot;4138&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4155&quot; data-start=&quot;4138&quot; data-section-id=&quot;1ng5ltm&quot;&gt;Ollama를 직접 돌려보고&lt;/li&gt;
&lt;li data-end=&quot;4173&quot; data-start=&quot;4156&quot; data-section-id=&quot;byka51&quot;&gt;작은 로컬 모델을 테스트하고&lt;/li&gt;
&lt;li data-end=&quot;4198&quot; data-start=&quot;4174&quot; data-section-id=&quot;1veo1l5&quot;&gt;Python AI 라이브러리를 사용해보고&lt;/li&gt;
&lt;li data-end=&quot;4220&quot; data-start=&quot;4199&quot; data-section-id=&quot;98rqxf&quot;&gt;RAG나 임베딩 같은 것을 실험하고&lt;/li&gt;
&lt;li data-end=&quot;4251&quot; data-start=&quot;4221&quot; data-section-id=&quot;1gjekxc&quot;&gt;Spring Boot 서비스와 AI를 연결해보는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;4256&quot; data-start=&quot;4253&quot; data-ke-size=&quot;size16&quot;&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;4341&quot; data-start=&quot;4258&quot; data-ke-size=&quot;size16&quot;&gt;더 큰 모델을 본격적으로 다루게 된다면 그때는 노트북을 다시 사는 게 아니라 &lt;b&gt;데스크톱 GPU나 클라우드 GPU를 사용하는 게 맞다고 생각한다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;4346&quot; data-start=&quot;4343&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;4376&quot; data-start=&quot;4348&quot; data-section-id=&quot;gy456d&quot; data-ke-size=&quot;size23&quot;&gt;결국 내가 찾던 건 가장 빠른 노트북이 아니었다&lt;/h3&gt;
&lt;p data-end=&quot;4412&quot; data-start=&quot;4378&quot; data-ke-size=&quot;size16&quot;&gt;노트북을 알아보기 전에는 그냥 좋은 걸 사면 되는 줄 알았다.&lt;/p&gt;
&lt;p data-end=&quot;4435&quot; data-start=&quot;4414&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이번에는 기준이 계속 바뀌었다.&lt;/p&gt;
&lt;p data-end=&quot;4445&quot; data-start=&quot;4437&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 성능.&lt;/p&gt;
&lt;p data-end=&quot;4456&quot; data-start=&quot;4447&quot; data-ke-size=&quot;size16&quot;&gt;그다음에는 무게.&lt;/p&gt;
&lt;p data-end=&quot;4468&quot; data-start=&quot;4458&quot; data-ke-size=&quot;size16&quot;&gt;그리고 화면 크기.&lt;/p&gt;
&lt;p data-end=&quot;4486&quot; data-start=&quot;4470&quot; data-ke-size=&quot;size16&quot;&gt;마지막에는 AI까지 들어왔다.&lt;/p&gt;
&lt;p data-end=&quot;4498&quot; data-start=&quot;4488&quot; data-ke-size=&quot;size16&quot;&gt;결국 내가 찾던 건&lt;/p&gt;
&lt;p data-end=&quot;4513&quot; data-start=&quot;4500&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;가장 빠른 노트북&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4520&quot; data-start=&quot;4515&quot; data-ke-size=&quot;size16&quot;&gt;이 아니라&lt;/p&gt;
&lt;p data-end=&quot;4567&quot; data-start=&quot;4522&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 실제로 들고 다니면서 앞으로 해보고 싶은 개발까지 할 수 있는 노트북&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4573&quot; data-start=&quot;4569&quot; data-ke-size=&quot;size16&quot;&gt;이었다.&lt;/p&gt;
&lt;p data-end=&quot;4582&quot; data-start=&quot;4575&quot; data-ke-size=&quot;size16&quot;&gt;그래서 현재는&lt;/p&gt;
&lt;blockquote data-end=&quot;4663&quot; data-start=&quot;4584&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;4663&quot; data-start=&quot;4586&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LG gram Pro 17&lt;br /&gt;Ultra 7 255H&lt;br /&gt;RAM 32GB&lt;br /&gt;SSD 1TB&lt;br /&gt;RTX 5050 8GB&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;4681&quot; data-start=&quot;4665&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4809&quot; data-start=&quot;4683&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4856&quot; data-start=&quot;4811&quot; data-ke-size=&quot;size16&quot;&gt;몇 년 전이라면 노트북을 고르면서 GPU를 게임 성능 정도로만 생각했을 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;4856&quot; data-start=&quot;4811&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4867&quot; data-start=&quot;4858&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 달랐다.&lt;/p&gt;
&lt;p data-end=&quot;4913&quot; data-start=&quot;4869&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AI를 직접 사용하기 시작하니 개발자의 노트북을 고르는 기준도 달라졌다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4952&quot; data-start=&quot;4915&quot; data-ke-size=&quot;size16&quot;&gt;아마 앞으로는 이런 고민을 하는 개발자가 더 많아지지 않을까 싶다.&lt;/p&gt;
&lt;p data-end=&quot;4952&quot; data-start=&quot;4915&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1236&quot; data-start=&quot;1159&quot; data-ke-size=&quot;size16&quot;&gt;그래서 현재는 이 모델을 가장 유력하게 보고 있다.&lt;/p&gt;
&lt;p data-end=&quot;1236&quot; data-start=&quot;1159&quot; data-ke-size=&quot;size16&quot;&gt;아직 실사용 후기는 아니다. 실제 구매를 위해 비교하면서 내린 현재의 선택이다.&lt;/p&gt;
&lt;div id=&quot;code_1790121100840&quot; data-ke-type=&quot;html&quot; data-source=&quot;&amp;lt;p&amp;gt;
이 글을 처음 쓸 때까지만 해도
RTX 5050이 들어간 그램 Pro 17을 가장 유력한 후보로 보고 있었다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
그리고 여러 모델과 가격을 더 비교한 끝에
결국 &amp;lt;strong&amp;gt;LG 그램 Pro 17 Ultra 7 구독&amp;lt;/strong&amp;gt;으로 결정했다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
처음에는 단순히 가볍고 화면이 큰 노트북을 찾았는데,
Ollama를 직접 돌려보면서 GPU와 VRAM까지 보게 됐고
결국 노트북 하나를 고르는 데 생각보다 많은 걸 공부하게 됐다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
아직 실사용 후기는 아니다.
노트북을 실제로 받으면 IntelliJ, Spring Boot, Docker 같은
내 개발환경을 그대로 옮겨보고,
Ollama도 직접 실행해볼 생각이다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
그때는 스펙표가 아니라
&amp;lt;strong&amp;gt;실제로 개발하면서 어느 정도까지 가능한지&amp;lt;/strong&amp;gt; 다시 정리해보려고 한다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
RAM 32GB와 SSD 1TB를 어디까지 가져갈지도 따로 고민했다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
  &amp;lt;a href=&amp;quot;https://nocklock.tistory.com/38&amp;quot;&amp;gt;
개발자 노트북 RAM 32GB&amp;middot;SSD 1TB면 충분할까? 그램 17 고르며 고민한 기준
&amp;lt;/a&amp;gt;
&amp;lt;/p&amp;gt;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글을 처음 쓸 때까지만 해도 RTX 5050이 들어간 그램 Pro 17을 가장 유력한 후보로 보고 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 여러 모델과 가격을 더 비교한 끝에 결국 &lt;b&gt;LG 그램 Pro 17 Ultra 7 구독&lt;/b&gt;으로 결정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 단순히 가볍고 화면이 큰 노트북을 찾았는데, Ollama를 직접 돌려보면서 GPU와 VRAM까지 보게 됐고 결국 노트북 하나를 고르는 데 생각보다 많은 걸 공부하게 됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 실사용 후기는 아니다. 노트북을 실제로 받으면 IntelliJ, Spring Boot, Docker 같은 내 개발환경을 그대로 옮겨보고, Ollama도 직접 실행해볼 생각이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그때는 스펙표가 아니라 &lt;b&gt;실제로 개발하면서 어느 정도까지 가능한지&lt;/b&gt; 다시 정리해보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RAM 32GB와 SSD 1TB를 어디까지 가져갈지도 따로 고민했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;a href=&quot;https://nocklock.tistory.com/38&quot;&gt; 개발자 노트북 RAM 32GB&amp;middot;SSD 1TB면 충분할까? 그램 17 고르며 고민한 기준 &lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1236&quot; data-start=&quot;1159&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1259&quot; data-start=&quot;1241&quot; data-ke-size=&quot;size16&quot;&gt;LG gram Pro 17 RTX 5050 구성 가격 확인하기 &amp;rarr;&lt;/p&gt;
&lt;div id=&quot;code_1790039058231&quot; data-ke-type=&quot;html&quot; data-source=&quot;
&amp;lt;div style=&amp;quot;margin:24px 0 32px;&amp;quot;&amp;gt;
  &amp;lt;a href=&amp;quot;https://link.coupang.com/a/he1WVKQPWS&amp;quot; target=&amp;quot;_blank&amp;quot; referrerpolicy=&amp;quot;unsafe-url&amp;quot;
     target=&amp;quot;_blank&amp;quot;
     rel=&amp;quot;sponsored nofollow noopener&amp;quot;
     style=&amp;quot;
       display:block;
       width:100%;
       box-sizing:border-box;
       padding:18px 20px;
       background:#182231;
       border:1px solid #6fe4c1;
       border-radius:12px;
       color:#ffffff;
       text-align:center;
       text-decoration:none;
       font-size:16px;
       font-weight:700;
       line-height:1.5;
     &amp;quot;&amp;gt;
    LG gram Pro 17 RTX 5050 현재 가격&amp;middot;구성 확인하기 &amp;rarr;
  &amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;&quot;&gt;
&lt;div style=&quot;margin: 24px 0 32px;&quot;&gt;&lt;a style=&quot;display: block; width: 100%; box-sizing: border-box; padding: 18px 20px; background: #182231; border: 1px solid #6fe4c1; border-radius: 12px; color: #ffffff; text-align: center; text-decoration: none; font-size: 16px; font-weight: bold; line-height: 1.5;&quot; href=&quot;https://link.coupang.com/a/he1WVKQPWS&quot; target=&quot;_blank&quot; rel=&quot;sponsored nofollow noopener&quot;&gt; LG gram Pro 17 RTX 5050 현재 가격&amp;middot;구성 확인하기 &amp;rarr; &lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;4957&quot; data-start=&quot;4954&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;4966&quot; data-start=&quot;4959&quot; data-section-id=&quot;1nfyygl&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4966&quot; data-start=&quot;4959&quot; data-section-id=&quot;1nfyygl&quot; data-ke-size=&quot;size18&quot;&gt;이전 글&lt;/p&gt;
&lt;p data-end=&quot;4966&quot; data-start=&quot;4959&quot; data-section-id=&quot;1nfyygl&quot; data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://nocklock.tistory.com/33&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;b&gt;-&amp;gt; 2026 개발자 노트북 추천 &amp;mdash; 입문용&amp;middot;실무용&amp;middot;휴대용으로 나눠봤다&lt;/b&gt;&lt;/a&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4966&quot; data-start=&quot;4959&quot; data-section-id=&quot;1nfyygl&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;5008&quot; data-start=&quot;4968&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;</description>
      <category>개발 노트</category>
      <category>AI개발</category>
      <category>AI노트북</category>
      <category>LG그램프로17</category>
      <category>ollama</category>
      <category>RTX5050</category>
      <category>ultra7</category>
      <category>개발용노트북</category>
      <category>개발자노트북</category>
      <category>그램프로17</category>
      <category>로컬llm</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/34</guid>
      <comments>https://nocklock.tistory.com/34#entry34comment</comments>
      <pubDate>Tue, 22 Sep 2026 10:05:02 +0900</pubDate>
    </item>
    <item>
      <title>2026 개발자 노트북 추천 &amp;mdash; 입문용&amp;middot;실무용&amp;middot;휴대용으로 나눠봤다</title>
      <link>https://nocklock.tistory.com/33</link>
      <description>&lt;p data-end=&quot;310&quot; data-start=&quot;284&quot; data-ke-size=&quot;size16&quot;&gt;개발용 노트북을 하나 사려고 알아보기 시작했다.&lt;/p&gt;
&lt;div id=&quot;code_1790038361496&quot; data-ke-type=&quot;html&quot; data-source=&quot;&amp;lt;p style=&amp;quot;font-size:14px; color:#666; line-height:1.6; margin-bottom:20px;&amp;quot;&amp;gt;
※ 이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
&amp;lt;/p&amp;gt;&quot;&gt;
&lt;p style=&quot;font-size: 14px; color: #666; line-height: 1.6; margin-bottom: 20px;&quot; data-ke-size=&quot;size16&quot;&gt;※ 이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 22일 오전 09_35_19.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2XOvk/dJMcabyWuze/Z8iA99Qv3nqDOVBfwkjr1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2XOvk/dJMcabyWuze/Z8iA99Qv3nqDOVBfwkjr1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2XOvk/dJMcabyWuze/Z8iA99Qv3nqDOVBfwkjr1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2XOvk%2FdJMcabyWuze%2FZ8iA99Qv3nqDOVBfwkjr1k%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; alt=&quot;무엇을 사야할까&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 22일 오전 09_35_19.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;310&quot; data-start=&quot;284&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;326&quot; data-start=&quot;312&quot; data-ke-size=&quot;size16&quot;&gt;노트북이 없는 건 아니다.&lt;/p&gt;
&lt;p data-end=&quot;369&quot; data-start=&quot;328&quot; data-ke-size=&quot;size16&quot;&gt;예전에 성능을 보고 산 게이밍 노트북도 있었다. 문제는 생각보다 단순했다.&lt;/p&gt;
&lt;p data-end=&quot;369&quot; data-start=&quot;328&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;391&quot; data-start=&quot;371&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;무거워서 잘 안 들고 다녔다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;449&quot; data-start=&quot;393&quot; data-ke-size=&quot;size16&quot;&gt;성능이 아무리 좋아도 집 책상 위에 계속 놓여 있다면, 나한테는 좋은 '노트북'이라고 하기 애매했다.&lt;/p&gt;
&lt;p data-end=&quot;477&quot; data-start=&quot;451&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번에는 조금 다르게 찾아보기 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;518&quot; data-start=&quot;479&quot; data-ke-size=&quot;size16&quot;&gt;그런데 막상 찾아보니 개발자 노트북이라는 것도 하나로 묶기가 어려웠다.&lt;/p&gt;
&lt;p data-end=&quot;604&quot; data-start=&quot;520&quot; data-ke-size=&quot;size16&quot;&gt;이제 막 Java나 Python을 배우는 사람과 IntelliJ, Docker, DB, 브라우저를 한꺼번에 띄우는 사람이 같은 사양을 살 필요는 없다.&lt;/p&gt;
&lt;p data-end=&quot;646&quot; data-start=&quot;606&quot; data-ke-size=&quot;size16&quot;&gt;반대로 성능보다 매일 들고 다닐 수 있는 무게가 더 중요한 사람도 있다.&lt;/p&gt;
&lt;p data-end=&quot;675&quot; data-start=&quot;648&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번에는 가격순이나 단순 스펙순이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;705&quot; data-start=&quot;677&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;입문 개발용 / 실무 개발용 / 휴대 개발용&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;718&quot; data-start=&quot;707&quot; data-ke-size=&quot;size16&quot;&gt;세 가지로 나눠봤다.&lt;/p&gt;
&lt;p data-end=&quot;759&quot; data-start=&quot;720&quot; data-ke-size=&quot;size16&quot;&gt;참고로 이 글은 세 제품을 직접 사용해보고 작성한 사용 후기는 아니다.&lt;/p&gt;
&lt;p data-end=&quot;802&quot; data-start=&quot;761&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 실제로 새 노트북을 구매하기 위해 비교하면서 정리한 내용이다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;807&quot; data-start=&quot;804&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;828&quot; data-start=&quot;809&quot; data-section-id=&quot;y6rm6e&quot; data-ke-size=&quot;size26&quot;&gt;개발용 노트북에서 먼저 본 것&lt;/h2&gt;
&lt;p data-end=&quot;851&quot; data-start=&quot;830&quot; data-ke-size=&quot;size16&quot;&gt;예전 같으면 CPU부터 봤을 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;877&quot; data-start=&quot;853&quot; data-ke-size=&quot;size16&quot;&gt;i5냐 i7이냐, 클럭이 얼마냐 같은 것들.&lt;/p&gt;
&lt;p data-end=&quot;895&quot; data-start=&quot;879&quot; data-ke-size=&quot;size16&quot;&gt;지금은 생각이 조금 달라졌다.&lt;/p&gt;
&lt;p data-end=&quot;967&quot; data-start=&quot;897&quot; data-ke-size=&quot;size16&quot;&gt;개발하면서 실제로 불편한 순간을 생각해보니 CPU 이름 하나보다 &lt;b&gt;메모리, 저장공간, 화면, 무게&lt;/b&gt;가 더 자주 체감됐다.&lt;/p&gt;
&lt;p data-end=&quot;1002&quot; data-start=&quot;969&quot; data-ke-size=&quot;size16&quot;&gt;특히 내 경우에는 이런 프로그램을 동시에 켜놓는 일이 많다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1088&quot; data-start=&quot;1004&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1014&quot; data-start=&quot;1004&quot; data-section-id=&quot;1njpu2l&quot;&gt;IntelliJ&lt;/li&gt;
&lt;li data-end=&quot;1028&quot; data-start=&quot;1015&quot; data-section-id=&quot;rvusbz&quot;&gt;Spring Boot&lt;/li&gt;
&lt;li data-end=&quot;1042&quot; data-start=&quot;1029&quot; data-section-id=&quot;1u5ooux&quot;&gt;브라우저 탭 여러 개&lt;/li&gt;
&lt;li data-end=&quot;1047&quot; data-start=&quot;1043&quot; data-section-id=&quot;yhmtri&quot;&gt;DB&lt;/li&gt;
&lt;li data-end=&quot;1053&quot; data-start=&quot;1048&quot; data-section-id=&quot;1o4hle&quot;&gt;Git&lt;/li&gt;
&lt;li data-end=&quot;1071&quot; data-start=&quot;1054&quot; data-section-id=&quot;170lw0n&quot;&gt;ChatGPT나 Claude&lt;/li&gt;
&lt;li data-end=&quot;1088&quot; data-start=&quot;1072&quot; data-section-id=&quot;3vnnkw&quot;&gt;가끔 Docker와 WSL&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1113&quot; data-start=&quot;1090&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번에는 몇 가지 기준부터 정했다.&lt;/p&gt;
&lt;h3 data-end=&quot;1136&quot; data-start=&quot;1115&quot; data-section-id=&quot;boliqu&quot; data-ke-size=&quot;size23&quot;&gt;RAM은 가능하면 16GB 이상&lt;/h3&gt;
&lt;p data-end=&quot;1169&quot; data-start=&quot;1138&quot; data-ke-size=&quot;size16&quot;&gt;코딩 공부만 한다면 아주 높은 사양까지 갈 필요는 없다.&lt;/p&gt;
&lt;p data-end=&quot;1227&quot; data-start=&quot;1171&quot; data-ke-size=&quot;size16&quot;&gt;그래도 지금 새 노트북을 산다면 개인적으로 &lt;b&gt;8GB보다는 16GB부터 보는 게 낫다고 생각했다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1274&quot; data-start=&quot;1229&quot; data-ke-size=&quot;size16&quot;&gt;IDE 하나만 켜는 게 아니라 브라우저와 여러 프로그램을 같이 사용하기 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;1328&quot; data-start=&quot;1276&quot; data-ke-size=&quot;size16&quot;&gt;그리고 실무에서 Docker나 여러 개발 도구를 같이 띄운다면 &lt;b&gt;32GB가 훨씬 편하다.&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-end=&quot;1362&quot; data-start=&quot;1330&quot; data-section-id=&quot;1fz8t2j&quot; data-ke-size=&quot;size23&quot;&gt;SSD 512GB는 시작점, 실무라면 1TB도 고려&lt;/h3&gt;
&lt;p data-end=&quot;1389&quot; data-start=&quot;1364&quot; data-ke-size=&quot;size16&quot;&gt;소스코드 자체는 용량을 많이 차지하지 않는다.&lt;/p&gt;
&lt;p data-end=&quot;1403&quot; data-start=&quot;1391&quot; data-ke-size=&quot;size16&quot;&gt;문제는 다른 것들이다.&lt;/p&gt;
&lt;p data-end=&quot;1475&quot; data-start=&quot;1405&quot; data-ke-size=&quot;size16&quot;&gt;IDE, SDK, Docker 이미지, WSL, DB, 각종 프로젝트와 캐시가 쌓이다 보면 생각보다 저장공간을 많이 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;1533&quot; data-start=&quot;1477&quot; data-ke-size=&quot;size16&quot;&gt;그래서 입문용은 512GB 정도면 시작할 만하지만, 여러 프로젝트를 오래 관리한다면 1TB가 편하다.&lt;/p&gt;
&lt;h3 data-end=&quot;1555&quot; data-start=&quot;1535&quot; data-section-id=&quot;1gakmnv&quot; data-ke-size=&quot;size23&quot;&gt;화면 크기도 생각보다 중요했다&lt;/h3&gt;
&lt;p data-end=&quot;1577&quot; data-start=&quot;1557&quot; data-ke-size=&quot;size16&quot;&gt;개발할 때는 코드만 보는 게 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1618&quot; data-start=&quot;1579&quot; data-ke-size=&quot;size16&quot;&gt;왼쪽에는 IDE를 띄우고 오른쪽에는 브라우저나 문서를 띄울 때도 많다.&lt;/p&gt;
&lt;p data-end=&quot;1666&quot; data-start=&quot;1620&quot; data-ke-size=&quot;size16&quot;&gt;외부 모니터가 있는 집에서는 괜찮지만 밖에서 개발한다면 화면 크기도 꽤 중요해진다.&lt;/p&gt;
&lt;p data-end=&quot;1676&quot; data-start=&quot;1668&quot; data-ke-size=&quot;size16&quot;&gt;그리고 마지막.&lt;/p&gt;
&lt;h3 data-end=&quot;1710&quot; data-start=&quot;1678&quot; data-section-id=&quot;1mycj4f&quot; data-ke-size=&quot;size23&quot;&gt;아무리 성능이 좋아도 안 들고 다니면 의미가 없었다&lt;/h3&gt;
&lt;p data-end=&quot;1729&quot; data-start=&quot;1712&quot; data-ke-size=&quot;size16&quot;&gt;이건 내가 이미 한 번 겪었다.&lt;/p&gt;
&lt;p data-end=&quot;1762&quot; data-start=&quot;1731&quot; data-ke-size=&quot;size16&quot;&gt;성능 좋은 노트북을 사놓고 무거워서 잘 안 들고 다녔다.&lt;/p&gt;
&lt;p data-end=&quot;1799&quot; data-start=&quot;1764&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번에는 &lt;b&gt;무게도 성능의 일부라고 생각하기로 했다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1804&quot; data-start=&quot;1801&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1836&quot; data-start=&quot;1806&quot; data-section-id=&quot;p48of9&quot; data-ke-size=&quot;size23&quot;&gt;1. 입문 개발용 &amp;mdash; ASUS Vivobook 16&lt;/h3&gt;
&lt;p data-end=&quot;1893&quot; data-start=&quot;1838&quot; data-ke-size=&quot;size16&quot;&gt;처음 개발 공부를 시작한다면 처음부터 200만~300만 원대 노트북이 필요한 건 아니라고 생각한다.&lt;/p&gt;
&lt;p data-end=&quot;1996&quot; data-start=&quot;1895&quot; data-ke-size=&quot;size16&quot;&gt;Java, Python, HTML/CSS/JavaScript를 공부하고 VS Code나 IntelliJ로 개인 프로젝트를 만드는 정도라면 우선 중요한 건 &lt;b&gt;기본기가 충분한가&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-end=&quot;2018&quot; data-start=&quot;1998&quot; data-ke-size=&quot;size16&quot;&gt;이번에 입문 개발용 후보로 본 제품은&lt;/p&gt;
&lt;p data-end=&quot;2057&quot; data-start=&quot;2020&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ASUS Vivobook 16 X1607CA-MB081W&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-end=&quot;2215&quot; data-start=&quot;2059&quot; data-ke-size=&quot;size16&quot;&gt;Core Ultra 5 225H, 16GB RAM, 512GB SSD, 16인치 1920&amp;times;1200 화면 구성이다. 메모리는 기본 16GB이고 추가 SO-DIMM 슬롯을 통해 최대 32GB까지 확장 가능한 구조다. &lt;span data-content-reference-end=&quot;2239&quot; data-content-reference-start=&quot;2197&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-end=&quot;2237&quot; data-start=&quot;2217&quot; data-section-id=&quot;1vlp15y&quot; data-ke-size=&quot;size23&quot;&gt;내가 이걸 입문용으로 본 이유&lt;/h3&gt;
&lt;p data-end=&quot;2263&quot; data-start=&quot;2239&quot; data-ke-size=&quot;size16&quot;&gt;가장 큰 이유는 &lt;b&gt;16GB RAM&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;2323&quot; data-start=&quot;2265&quot; data-ke-size=&quot;size16&quot;&gt;개발 입문용이라고 해서 너무 낮은 사양을 사면 조금만 사용 범위가 넓어져도 다시 노트북을 고민하게 된다.&lt;/p&gt;
&lt;p data-end=&quot;2396&quot; data-start=&quot;2325&quot; data-ke-size=&quot;size16&quot;&gt;이 정도면 일반적인 웹 개발 공부와 Java/Python 프로젝트를 시작하면서 바로 부족함을 느낄 가능성은 비교적 낮아 보였다.&lt;/p&gt;
&lt;p data-end=&quot;2425&quot; data-start=&quot;2398&quot; data-ke-size=&quot;size16&quot;&gt;16인치 16:10 화면도 코드를 보기에 괜찮다.&lt;/p&gt;
&lt;p data-end=&quot;2507&quot; data-start=&quot;2427&quot; data-ke-size=&quot;size16&quot;&gt;반대로 약 &lt;b&gt;1.89kg&lt;/b&gt;이라 휴대성이 뛰어난 제품이라고 하기는 어렵다. &lt;span data-content-reference-end=&quot;2518&quot; data-content-reference-start=&quot;2494&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2521&quot; data-start=&quot;2509&quot; data-ke-size=&quot;size16&quot;&gt;그래서 나는 이 제품을&lt;/p&gt;
&lt;p data-end=&quot;2566&quot; data-start=&quot;2523&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;매일 들고 다니는 노트북보다는 가격과 개발 성능의 균형을 원하는 입문자&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2575&quot; data-start=&quot;2568&quot; data-ke-size=&quot;size16&quot;&gt;쪽으로 봤다.&lt;/p&gt;
&lt;p data-end=&quot;2586&quot; data-start=&quot;2577&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추천 대상&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2688&quot; data-start=&quot;2588&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2604&quot; data-start=&quot;2588&quot; data-section-id=&quot;iowbvd&quot;&gt;개발을 처음 시작하는 사람&lt;/li&gt;
&lt;li data-end=&quot;2630&quot; data-start=&quot;2605&quot; data-section-id=&quot;1lyuaks&quot;&gt;Java / Python / 웹 개발 공부&lt;/li&gt;
&lt;li data-end=&quot;2661&quot; data-start=&quot;2631&quot; data-section-id=&quot;19024kc&quot;&gt;VS Code나 IntelliJ 기반 개인 프로젝트&lt;/li&gt;
&lt;li data-end=&quot;2688&quot; data-start=&quot;2662&quot; data-section-id=&quot;10jseea&quot;&gt;16GB RAM 이상으로 시작하고 싶은 사람&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2699&quot; data-start=&quot;2690&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아쉬운 점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2752&quot; data-start=&quot;2701&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2713&quot; data-start=&quot;2701&quot; data-section-id=&quot;r7hka7&quot;&gt;512GB 저장공간&lt;/li&gt;
&lt;li data-end=&quot;2726&quot; data-start=&quot;2714&quot; data-section-id=&quot;g5z01m&quot;&gt;1.89kg의 무게&lt;/li&gt;
&lt;li data-end=&quot;2752&quot; data-start=&quot;2727&quot; data-section-id=&quot;kx1jg7&quot;&gt;본격적인 GPU 작업을 위한 노트북은 아님&lt;/li&gt;
&lt;/ul&gt;
&lt;div id=&quot;code_1790037063468&quot; data-ke-type=&quot;html&quot; data-source=&quot;
&amp;lt;!-- ASUS Vivobook 16 --&amp;gt;
&amp;lt;div style=&amp;quot;margin:22px 0 30px;&amp;quot;&amp;gt;
  &amp;lt;a href=&amp;quot;https://link.coupang.com/a/heYjTz1FPo&amp;quot; target=&amp;quot;_blank&amp;quot; referrerpolicy=&amp;quot;unsafe-url&amp;quot;
     target=&amp;quot;_blank&amp;quot;
     rel=&amp;quot;sponsored nofollow noopener&amp;quot;
     style=&amp;quot;display:block; width:100%; box-sizing:border-box;
            padding:17px 20px;
            background:#182231;
            border:1px solid #6fe4c1;
            border-radius:12px;
            color:#ffffff;
            text-align:center;
            text-decoration:none;
            font-size:16px;
            font-weight:700;
            line-height:1.5;&amp;quot;&amp;gt;
    ASUS Vivobook 16 현재 가격&amp;middot;구성 확인하기 &amp;rarr;
  &amp;lt;/a&amp;gt;&quot;&gt;&lt;!-- ASUS Vivobook 16 --&gt;
&lt;div style=&quot;margin: 22px 0 30px;&quot;&gt;&lt;a style=&quot;display: block; width: 100%; box-sizing: border-box; padding: 17px 20px; background: #182231; border: 1px solid #6fe4c1; border-radius: 12px; color: #ffffff; text-align: center; text-decoration: none; font-size: 16px; font-weight: bold; line-height: 1.5;&quot; href=&quot;https://link.coupang.com/a/heYjTz1FPo&quot; target=&quot;_blank&quot; rel=&quot;sponsored nofollow noopener&quot;&gt; ASUS Vivobook 16 현재 가격&amp;middot;구성 확인하기 &amp;rarr; &lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2871&quot; data-start=&quot;2807&quot; data-ke-size=&quot;size16&quot;&gt;※ 가격과 판매 옵션은 시점에 따라 달라질 수 있으니 구매 전 RAM&amp;middot;SSD&amp;middot;운영체제 구성을 확인하는 것을 권한다.&lt;/p&gt;
&lt;hr data-end=&quot;2876&quot; data-start=&quot;2873&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2917&quot; data-start=&quot;2878&quot; data-section-id=&quot;1sgk6hq&quot; data-ke-size=&quot;size23&quot;&gt;2. 실무 개발용 &amp;mdash; Lenovo ThinkPad E16 Gen 3&lt;/h3&gt;
&lt;p data-end=&quot;2941&quot; data-start=&quot;2919&quot; data-ke-size=&quot;size16&quot;&gt;실무로 넘어가면 이야기가 조금 달라진다.&lt;/p&gt;
&lt;p data-end=&quot;2977&quot; data-start=&quot;2943&quot; data-ke-size=&quot;size16&quot;&gt;회사에서 개발할 때는 IntelliJ만 켜놓고 일하지 않는다.&lt;/p&gt;
&lt;p data-end=&quot;3038&quot; data-start=&quot;2979&quot; data-ke-size=&quot;size16&quot;&gt;브라우저 탭을 여러 개 띄우고 DB를 연결하고, 로컬 서버를 돌리고, 메신저와 문서까지 같이 켜놓게 된다.&lt;/p&gt;
&lt;p data-end=&quot;3072&quot; data-start=&quot;3040&quot; data-ke-size=&quot;size16&quot;&gt;Docker까지 사용하기 시작하면 메모리를 더 쓰게 된다.&lt;/p&gt;
&lt;p data-end=&quot;3120&quot; data-start=&quot;3074&quot; data-ke-size=&quot;size16&quot;&gt;그래서 실무용에서는 CPU 이름보다 먼저 &lt;b&gt;32GB RAM&lt;/b&gt;을 기준으로 잡았다.&lt;/p&gt;
&lt;p data-end=&quot;3131&quot; data-start=&quot;3122&quot; data-ke-size=&quot;size16&quot;&gt;이번에 본 제품은&lt;/p&gt;
&lt;p data-end=&quot;3173&quot; data-start=&quot;3133&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Lenovo ThinkPad E16 Gen 3 21SR002CKD&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3329&quot; data-start=&quot;3175&quot; data-ke-size=&quot;size16&quot;&gt;이고, 쿠팡에서는 판매 옵션에 따라 &lt;b&gt;32GB RAM + 1TB SSD&lt;/b&gt; 구성도 선택할 수 있다. 기본 모델은 Ultra 5 225H 기반이며 제품군 자체는 DDR5 메모리 슬롯과 SSD 확장을 지원한다. &lt;span data-content-reference-end=&quot;3346&quot; data-content-reference-start=&quot;3303&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-end=&quot;3353&quot; data-start=&quot;3331&quot; data-section-id=&quot;100wz33&quot; data-ke-size=&quot;size23&quot;&gt;왜 실무형에서는 32GB를 골랐나&lt;/h3&gt;
&lt;p data-end=&quot;3377&quot; data-start=&quot;3355&quot; data-ke-size=&quot;size16&quot;&gt;내 데스크톱도 현재 RAM이 16GB다.&lt;/p&gt;
&lt;p data-end=&quot;3441&quot; data-start=&quot;3379&quot; data-ke-size=&quot;size16&quot;&gt;개발하면서 프로그램을 여러 개 켜놓다 보면 16GB가 당장 못 쓸 정도는 아니지만 여유롭다고 느껴지지도 않는다.&lt;/p&gt;
&lt;p data-end=&quot;3493&quot; data-start=&quot;3443&quot; data-ke-size=&quot;size16&quot;&gt;새 노트북을 몇 년 사용할 생각이라면 실무형에서는 개인적으로 32GB 쪽이 마음이 편하다.&lt;/p&gt;
&lt;p data-end=&quot;3497&quot; data-start=&quot;3495&quot; data-ke-size=&quot;size16&quot;&gt;특히&lt;/p&gt;
&lt;p data-end=&quot;3540&quot; data-start=&quot;3499&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;IntelliJ + Docker + DB + 브라우저 + AI 도구&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3565&quot; data-start=&quot;3542&quot; data-ke-size=&quot;size16&quot;&gt;를 동시에 사용하는 개발자라면 더 그렇다.&lt;/p&gt;
&lt;p data-end=&quot;3608&quot; data-start=&quot;3567&quot; data-ke-size=&quot;size16&quot;&gt;저장공간도 1TB 구성으로 선택하면 512GB보다 신경을 덜 쓸 수 있다.&lt;/p&gt;
&lt;h3 data-end=&quot;3629&quot; data-start=&quot;3610&quot; data-section-id=&quot;8ofzig&quot; data-ke-size=&quot;size23&quot;&gt;ThinkPad를 넣은 이유&lt;/h3&gt;
&lt;p data-end=&quot;3666&quot; data-start=&quot;3631&quot; data-ke-size=&quot;size16&quot;&gt;성능표에서 가장 높은 숫자를 가진 노트북이라서 넣은 건 아니다.&lt;/p&gt;
&lt;p data-end=&quot;3866&quot; data-start=&quot;3668&quot; data-ke-size=&quot;size16&quot;&gt;ThinkPad E16은 애초에 업무용 성격이 강하고, 16인치 화면과 확장 가능한 메모리/스토리지 구성이 실무용 후보에 잘 맞았다. Lenovo의 공식 E16 Gen 3 사양에서도 해당 프로세서 계열은 두 개의 DDR5 SODIMM 슬롯과 최대 두 개의 M.2 SSD 구성을 지원한다. &lt;span data-content-reference-end=&quot;3871&quot; data-content-reference-start=&quot;3846&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3885&quot; data-start=&quot;3868&quot; data-ke-size=&quot;size16&quot;&gt;다만 여기서 주의할 점이 있다.&lt;/p&gt;
&lt;p data-end=&quot;3902&quot; data-start=&quot;3887&quot; data-ke-size=&quot;size16&quot;&gt;같은 모델 번호라도 판매자가&lt;/p&gt;
&lt;p data-end=&quot;3931&quot; data-start=&quot;3904&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;16GB / 512GB / Free DOS&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3935&quot; data-start=&quot;3933&quot; data-ke-size=&quot;size16&quot;&gt;또는&lt;/p&gt;
&lt;p data-end=&quot;3964&quot; data-start=&quot;3937&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;32GB / 1TB / Windows 11&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3982&quot; data-start=&quot;3966&quot; data-ke-size=&quot;size16&quot;&gt;처럼 옵션을 다르게 판매한다.&lt;/p&gt;
&lt;p data-end=&quot;4100&quot; data-start=&quot;3984&quot; data-ke-size=&quot;size16&quot;&gt;쿠팡에서도 실제로 여러 구성이 확인되기 때문에 링크에 들어가서 &lt;b&gt;RAM, SSD, Windows 포함 여부를 반드시 확인하는 게 좋다.&lt;/b&gt; &lt;span data-content-reference-end=&quot;4110&quot; data-content-reference-start=&quot;4068&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;4111&quot; data-start=&quot;4102&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추천 대상&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4237&quot; data-start=&quot;4113&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4153&quot; data-start=&quot;4113&quot; data-section-id=&quot;ooax7a&quot;&gt;IntelliJ / Eclipse 등 IDE를 장시간 사용하는 개발자&lt;/li&gt;
&lt;li data-end=&quot;4171&quot; data-start=&quot;4154&quot; data-section-id=&quot;9qo0o9&quot;&gt;Docker를 사용하는 사람&lt;/li&gt;
&lt;li data-end=&quot;4197&quot; data-start=&quot;4172&quot; data-section-id=&quot;18vfsm2&quot;&gt;여러 프로젝트와 DB를 동시에 띄우는 사람&lt;/li&gt;
&lt;li data-end=&quot;4216&quot; data-start=&quot;4198&quot; data-section-id=&quot;3rr3ci&quot;&gt;RAM 32GB를 원하는 사람&lt;/li&gt;
&lt;li data-end=&quot;4237&quot; data-start=&quot;4217&quot; data-section-id=&quot;hh9370&quot;&gt;업무용 노트북을 오래 사용할 사람&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;4248&quot; data-start=&quot;4239&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아쉬운 점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4319&quot; data-start=&quot;4250&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4264&quot; data-start=&quot;4250&quot; data-section-id=&quot;h9hpv3&quot;&gt;입문용보다 가격이 높음&lt;/li&gt;
&lt;li data-end=&quot;4295&quot; data-start=&quot;4265&quot; data-section-id=&quot;752dtk&quot;&gt;구성에 따라 Windows가 포함되지 않을 수 있음&lt;/li&gt;
&lt;li data-end=&quot;4319&quot; data-start=&quot;4296&quot; data-section-id=&quot;1aqdkok&quot;&gt;가벼움을 최우선으로 고르는 제품은 아님&lt;/li&gt;
&lt;/ul&gt;
&lt;div id=&quot;code_1790037079970&quot; data-ke-type=&quot;html&quot; data-source=&quot;
&amp;lt;div style=&amp;quot;margin:22px 0 30px;&amp;quot;&amp;gt;
  &amp;lt;a href=&amp;quot;https://link.coupang.com/a/heYGRY9ztQ&amp;quot; target=&amp;quot;_blank&amp;quot; referrerpolicy=&amp;quot;unsafe-url&amp;quot;
     target=&amp;quot;_blank&amp;quot;
     rel=&amp;quot;sponsored nofollow noopener&amp;quot;
     style=&amp;quot;
       display:block;
       width:100%;
       box-sizing:border-box;
       padding:17px 20px;
       background:#182231;
       border:1px solid #6fe4c1;
       border-radius:12px;
       color:#ffffff;
       text-align:center;
       text-decoration:none;
       font-size:16px;
       font-weight:700;
       line-height:1.5;
     &amp;quot;&amp;gt;
    Lenovo ThinkPad E16 Gen 3 현재 가격&amp;middot;구성 확인하기 &amp;rarr;
  &amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;&quot;&gt;
&lt;div style=&quot;margin: 22px 0 30px;&quot;&gt;&lt;a style=&quot;display: block; width: 100%; box-sizing: border-box; padding: 17px 20px; background: #182231; border: 1px solid #6fe4c1; border-radius: 12px; color: #ffffff; text-align: center; text-decoration: none; font-size: 16px; font-weight: bold; line-height: 1.5;&quot; href=&quot;https://link.coupang.com/a/heYGRY9ztQ&quot; target=&quot;_blank&quot; rel=&quot;sponsored nofollow noopener&quot;&gt; Lenovo ThinkPad E16 Gen 3 현재 가격&amp;middot;구성 확인하기 &amp;rarr; &lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;4381&quot; data-start=&quot;4378&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;4407&quot; data-start=&quot;4383&quot; data-section-id=&quot;nzjt0n&quot; data-ke-size=&quot;size23&quot;&gt;3. 휴대 개발용 &amp;mdash; LG gram 16&lt;/h3&gt;
&lt;p data-end=&quot;4425&quot; data-start=&quot;4409&quot; data-ke-size=&quot;size16&quot;&gt;마지막은 조금 다른 기준이다.&lt;/p&gt;
&lt;p data-end=&quot;4452&quot; data-start=&quot;4427&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;성능보다 실제로 들고 다닐 수 있는가.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4480&quot; data-start=&quot;4454&quot; data-ke-size=&quot;size16&quot;&gt;이 기준을 따로 넣은 이유는 내 경험 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;4513&quot; data-start=&quot;4482&quot; data-ke-size=&quot;size16&quot;&gt;예전에 사용하던 노트북도 성능 자체가 나쁜 건 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;4524&quot; data-start=&quot;4515&quot; data-ke-size=&quot;size16&quot;&gt;그런데 무거웠다.&lt;/p&gt;
&lt;p data-end=&quot;4572&quot; data-start=&quot;4526&quot; data-ke-size=&quot;size16&quot;&gt;노트북을 들고 카페나 다른 곳에 가려고 하면 노트북 본체에 충전기까지 챙겨야 했다.&lt;/p&gt;
&lt;p data-end=&quot;4584&quot; data-start=&quot;4574&quot; data-ke-size=&quot;size16&quot;&gt;한두 번은 괜찮다.&lt;/p&gt;
&lt;p data-end=&quot;4619&quot; data-start=&quot;4586&quot; data-ke-size=&quot;size16&quot;&gt;그런데 계속 반복되면 어느 순간 그냥 안 들고 나가게 된다.&lt;/p&gt;
&lt;p data-end=&quot;4658&quot; data-start=&quot;4621&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번에 새 노트북을 알아보면서 LG 그램을 계속 보게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;4684&quot; data-start=&quot;4660&quot; data-ke-size=&quot;size16&quot;&gt;이번 글의 휴대형 후보는 쿠팡에서 판매 중인&lt;/p&gt;
&lt;p data-end=&quot;4716&quot; data-start=&quot;4686&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LG gram 16 / 16ZB90S-GA5PK&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4720&quot; data-start=&quot;4718&quot; data-ke-size=&quot;size16&quot;&gt;다.&lt;/p&gt;
&lt;p data-end=&quot;4832&quot; data-start=&quot;4722&quot; data-ke-size=&quot;size16&quot;&gt;현재 판매 페이지에서는 Ultra 5, RAM 16GB, SSD 512GB, Windows 11 Home 구성으로 판매되고 있다. &lt;span data-content-reference-end=&quot;4829&quot; data-content-reference-start=&quot;4805&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;4927&quot; data-start=&quot;4834&quot; data-ke-size=&quot;size16&quot;&gt;비슷한 16Z90S 계열 공식 사양은 16인치급 화면에 약 &lt;b&gt;1.2kg&lt;/b&gt; 수준의 무게를 갖는다. &lt;span data-content-reference-end=&quot;4911&quot; data-content-reference-start=&quot;4887&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-end=&quot;4963&quot; data-start=&quot;4929&quot; data-section-id=&quot;jwex62&quot; data-ke-size=&quot;size23&quot;&gt;이 제품은 성능 때문에 골랐다기보다 무게 때문에 골랐다&lt;/h3&gt;
&lt;p data-end=&quot;4998&quot; data-start=&quot;4965&quot; data-ke-size=&quot;size16&quot;&gt;입문용 ASUS와 실무용 ThinkPad와는 기준이 다르다.&lt;/p&gt;
&lt;p data-end=&quot;5015&quot; data-start=&quot;5000&quot; data-ke-size=&quot;size16&quot;&gt;그램의 가장 큰 장점은 결국&lt;/p&gt;
&lt;p data-end=&quot;5040&quot; data-start=&quot;5017&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;큰 화면을 가지고 다니기 쉽다는 것&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;5051&quot; data-start=&quot;5042&quot; data-ke-size=&quot;size16&quot;&gt;이라고 생각한다.&lt;/p&gt;
&lt;p data-end=&quot;5076&quot; data-start=&quot;5053&quot; data-ke-size=&quot;size16&quot;&gt;개발자는 화면이 클수록 편한 순간이 많다.&lt;/p&gt;
&lt;p data-end=&quot;5102&quot; data-start=&quot;5078&quot; data-ke-size=&quot;size16&quot;&gt;그런데 화면을 키우면 보통 무게도 늘어난다.&lt;/p&gt;
&lt;p data-end=&quot;5128&quot; data-start=&quot;5104&quot; data-ke-size=&quot;size16&quot;&gt;그램은 이 둘 사이에서 특이한 위치에 있다.&lt;/p&gt;
&lt;p data-end=&quot;5219&quot; data-start=&quot;5130&quot; data-ke-size=&quot;size16&quot;&gt;다만 16GB RAM이 온보드인 구성이라, 실무에서 Docker와 여러 개발 프로그램을 아주 많이 사용하는 사람이라면 32GB 모델도 같이 비교하는 편이 좋다.&lt;/p&gt;
&lt;p data-end=&quot;5232&quot; data-start=&quot;5221&quot; data-ke-size=&quot;size16&quot;&gt;그리고 한 가지 더.&lt;/p&gt;
&lt;p data-end=&quot;5309&quot; data-start=&quot;5234&quot; data-ke-size=&quot;size16&quot;&gt;판매 페이지에 붙은 연식이나 'AI'라는 이름만 보고 선택하기보다는 &lt;b&gt;실제 CPU와 RAM, SSD 구성을 확인하는 게 중요하다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;5340&quot; data-start=&quot;5311&quot; data-ke-size=&quot;size16&quot;&gt;나도 이번에 노트북을 찾으면서 이걸 꽤 많이 느꼈다.&lt;/p&gt;
&lt;p data-end=&quot;5351&quot; data-start=&quot;5342&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추천 대상&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;5438&quot; data-start=&quot;5353&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;5373&quot; data-start=&quot;5353&quot; data-section-id=&quot;gmxkhl&quot;&gt;노트북을 매일 들고 다니는 개발자&lt;/li&gt;
&lt;li data-end=&quot;5389&quot; data-start=&quot;5374&quot; data-section-id=&quot;1abfy7c&quot;&gt;큰 화면을 선호하는 사람&lt;/li&gt;
&lt;li data-end=&quot;5414&quot; data-start=&quot;5390&quot; data-section-id=&quot;c4oein&quot;&gt;카페나 외부에서 코딩하는 일이 많은 사람&lt;/li&gt;
&lt;li data-end=&quot;5438&quot; data-start=&quot;5415&quot; data-section-id=&quot;akqjlx&quot;&gt;성능과 함께 무게를 중요하게 보는 사람&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;5449&quot; data-start=&quot;5440&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아쉬운 점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;5553&quot; data-start=&quot;5451&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;5481&quot; data-start=&quot;5451&quot; data-section-id=&quot;wb4dhl&quot;&gt;비슷한 성능의 일반 노트북보다 가격이 높을 수 있음&lt;/li&gt;
&lt;li data-end=&quot;5518&quot; data-start=&quot;5482&quot; data-section-id=&quot;1tzv320&quot;&gt;16GB RAM 구성은 무거운 실무 환경에서는 아쉬울 수 있음&lt;/li&gt;
&lt;li data-end=&quot;5553&quot; data-start=&quot;5519&quot; data-section-id=&quot;4whaoe&quot;&gt;로컬 AI 같은 GPU 중심 작업에는 별도의 고민이 필요함&lt;/li&gt;
&lt;/ul&gt;
&lt;div id=&quot;code_1790036703870&quot; data-ke-type=&quot;html&quot; data-source=&quot;
&amp;lt;div style=&amp;quot;margin:22px 0 30px;&amp;quot;&amp;gt;
  &amp;lt;a href=&amp;quot;https://link.coupang.com/a/heYKxeCmMC&amp;quot; target=&amp;quot;_blank&amp;quot; referrerpolicy=&amp;quot;unsafe-url&amp;quot;
     target=&amp;quot;_blank&amp;quot;
     rel=&amp;quot;sponsored nofollow noopener&amp;quot;
     style=&amp;quot;
       display:block;
       width:100%;
       box-sizing:border-box;
       padding:17px 20px;
       background:#182231;
       border:1px solid #6fe4c1;
       border-radius:12px;
       color:#ffffff;
       text-align:center;
       text-decoration:none;
       font-size:16px;
       font-weight:700;
       line-height:1.5;
     &amp;quot;&amp;gt;
    LG gram 16 현재 가격&amp;middot;구성 확인하기 &amp;rarr;
  &amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;&quot;&gt;
&lt;div style=&quot;margin: 22px 0 30px;&quot;&gt;&lt;a style=&quot;display: block; width: 100%; box-sizing: border-box; padding: 17px 20px; background: #182231; border: 1px solid #6fe4c1; border-radius: 12px; color: #ffffff; text-align: center; text-decoration: none; font-size: 16px; font-weight: bold; line-height: 1.5;&quot; href=&quot;https://link.coupang.com/a/heYKxeCmMC&quot; target=&quot;_blank&quot; rel=&quot;sponsored nofollow noopener&quot;&gt; LG gram 16 현재 가격&amp;middot;구성 확인하기 &amp;rarr; &lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-end=&quot;5633&quot; data-start=&quot;5616&quot; data-section-id=&quot;1gh5she&quot;&gt;세 제품을 한 번에 비교하면&lt;/h1&gt;
&lt;div&gt;
&lt;div&gt;구분입문 개발용실무 개발용휴대 개발용
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;5983&quot; data-start=&quot;5635&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;5983&quot; data-start=&quot;5687&quot;&gt;
&lt;tr data-end=&quot;5746&quot; data-start=&quot;5687&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5692&quot; data-start=&quot;5687&quot;&gt;제품&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5711&quot; data-start=&quot;5692&quot;&gt;ASUS Vivobook 16&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5732&quot; data-start=&quot;5711&quot;&gt;ThinkPad E16 Gen 3&lt;/td&gt;
&lt;td data-end=&quot;5746&quot; data-start=&quot;5732&quot; data-col-size=&quot;sm&quot;&gt;LG gram 16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5785&quot; data-start=&quot;5747&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5753&quot; data-start=&quot;5747&quot;&gt;RAM&lt;/td&gt;
&lt;td data-end=&quot;5760&quot; data-start=&quot;5753&quot; data-col-size=&quot;sm&quot;&gt;16GB&lt;/td&gt;
&lt;td data-end=&quot;5777&quot; data-start=&quot;5760&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;32GB 구성 추천&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;5785&quot; data-start=&quot;5777&quot; data-col-size=&quot;sm&quot;&gt;16GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5825&quot; data-start=&quot;5786&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5792&quot; data-start=&quot;5786&quot;&gt;SSD&lt;/td&gt;
&lt;td data-end=&quot;5800&quot; data-start=&quot;5792&quot; data-col-size=&quot;sm&quot;&gt;512GB&lt;/td&gt;
&lt;td data-end=&quot;5816&quot; data-start=&quot;5800&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;1TB 구성 추천&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;5825&quot; data-start=&quot;5816&quot; data-col-size=&quot;sm&quot;&gt;512GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5853&quot; data-start=&quot;5826&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5831&quot; data-start=&quot;5826&quot;&gt;화면&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5838&quot; data-start=&quot;5831&quot;&gt;16인치&lt;/td&gt;
&lt;td data-end=&quot;5845&quot; data-start=&quot;5838&quot; data-col-size=&quot;sm&quot;&gt;16인치&lt;/td&gt;
&lt;td data-end=&quot;5853&quot; data-start=&quot;5845&quot; data-col-size=&quot;sm&quot;&gt;16인치&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5893&quot; data-start=&quot;5854&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5859&quot; data-start=&quot;5854&quot;&gt;장점&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5870&quot; data-start=&quot;5859&quot;&gt;가격/성능 균형&lt;/td&gt;
&lt;td data-end=&quot;5882&quot; data-start=&quot;5870&quot; data-col-size=&quot;sm&quot;&gt;멀티태스킹&amp;middot;확장성&lt;/td&gt;
&lt;td data-end=&quot;5893&quot; data-start=&quot;5882&quot; data-col-size=&quot;sm&quot;&gt;&lt;b&gt;휴대성&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5946&quot; data-start=&quot;5894&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5905&quot; data-start=&quot;5894&quot;&gt;내가 보는 용도&lt;/td&gt;
&lt;td data-end=&quot;5921&quot; data-start=&quot;5905&quot; data-col-size=&quot;sm&quot;&gt;개발 공부&amp;middot;개인 프로젝트&lt;/td&gt;
&lt;td data-end=&quot;5934&quot; data-start=&quot;5921&quot; data-col-size=&quot;sm&quot;&gt;본격적인 실무 개발&lt;/td&gt;
&lt;td data-end=&quot;5946&quot; data-start=&quot;5934&quot; data-col-size=&quot;sm&quot;&gt;외부 개발&amp;middot;이동&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;5983&quot; data-start=&quot;5947&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;5955&quot; data-start=&quot;5947&quot;&gt;주의할 점&lt;/td&gt;
&lt;td data-end=&quot;5960&quot; data-start=&quot;5955&quot; data-col-size=&quot;sm&quot;&gt;무게&lt;/td&gt;
&lt;td data-end=&quot;5972&quot; data-start=&quot;5960&quot; data-col-size=&quot;sm&quot;&gt;옵션별 사양 차이&lt;/td&gt;
&lt;td data-end=&quot;5983&quot; data-start=&quot;5972&quot; data-col-size=&quot;sm&quot;&gt;RAM&amp;middot;GPU&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6018&quot; data-start=&quot;5985&quot; data-ke-size=&quot;size16&quot;&gt;사실 세 제품 중 하나가 무조건 제일 좋다고 하기는 어렵다.&lt;/p&gt;
&lt;p data-end=&quot;6062&quot; data-start=&quot;6020&quot; data-ke-size=&quot;size16&quot;&gt;개발 공부를 시작하는 사람에게 300만 원짜리 노트북이 필요한 것도 아니고,&lt;/p&gt;
&lt;p data-end=&quot;6113&quot; data-start=&quot;6064&quot; data-ke-size=&quot;size16&quot;&gt;매일 Docker와 IDE를 여러 개 돌리는 사람이 메모리를 지나치게 아낄 필요도 없다.&lt;/p&gt;
&lt;p data-end=&quot;6178&quot; data-start=&quot;6115&quot; data-ke-size=&quot;size16&quot;&gt;그리고 나처럼 &lt;b&gt;좋은 성능의 노트북을 사놓고 무거워서 안 들고 다닌 경험이 있다면 무게를 무시하기도 어렵다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;6202&quot; data-start=&quot;6180&quot; data-ke-size=&quot;size16&quot;&gt;결국 개발용 노트북을 고를 때 중요한 건&lt;/p&gt;
&lt;blockquote data-end=&quot;6220&quot; data-start=&quot;6204&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;6220&quot; data-start=&quot;6206&quot; data-ke-size=&quot;size16&quot;&gt;가장 높은 스펙이 무엇인가&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;6224&quot; data-start=&quot;6222&quot; data-ke-size=&quot;size16&quot;&gt;보다&lt;/p&gt;
&lt;blockquote data-end=&quot;6252&quot; data-start=&quot;6226&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;6252&quot; data-start=&quot;6228&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 실제로 어떤 방식으로 개발하는가&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;6261&quot; data-start=&quot;6254&quot; data-ke-size=&quot;size16&quot;&gt;에 가까웠다.&lt;/p&gt;
&lt;hr data-end=&quot;6266&quot; data-start=&quot;6263&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;div id=&quot;code_1790120777736&quot; data-ke-type=&quot;html&quot; data-source=&quot;&amp;lt;h2&amp;gt;결국 나는 LG 그램 17 Ultra 7로 결정했다&amp;lt;/h2&amp;gt;

&amp;lt;p&amp;gt;
처음 이 글을 정리할 때까지만 해도 내가 살 노트북은 아직 정하지 못했다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
개발용이면 어느 정도 사양이면 충분한지,
휴대성을 어디까지 포기할 수 있는지 계속 비교했다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
그러다 Ollama 같은 로컬 AI까지 생각하면서
RTX 5050이 들어간 그램 Pro까지 보게 됐다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
그런데 가격, 무게, 실제로 내가 가장 많이 하는 작업을 다시 생각해보니
결국 &amp;lt;strong&amp;gt;LG 그램 17 Ultra 7 구독&amp;lt;/strong&amp;gt;으로 결정했다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
최고 사양을 고른 건 아니다.
오히려 내가 매일 사용할 환경에서 무엇이 더 중요한지를 따져본 결과에 가깝다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
RTX 5050까지 고민했던 과정은 아래 글에 따로 정리했다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
  &amp;lt;a href=&amp;quot;https://nocklock.tistory.com/34&amp;quot;&amp;gt;
LG 그램 Pro 17 개발용으로 괜찮을까? AI&amp;middot;Ollama 때문에 RTX 5050까지 고민했다
&amp;lt;/a&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
그리고 RAM과 SSD를 어디까지 가져갈지는 생각보다 더 오래 고민했다.
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
  &amp;lt;a href=&amp;quot;https://nocklock.tistory.com/38&amp;quot;&amp;gt;
개발자 노트북 RAM 32GB&amp;middot;SSD 1TB면 충분할까? 그램 17 고르며 고민한 기준
&amp;lt;/a&amp;gt;
&amp;lt;/p&amp;gt;&quot;&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결국 나는 LG 그램 17 Ultra 7로 결정했다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 이 글을 정리할 때까지만 해도 내가 살 노트북은 아직 정하지 못했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발용이면 어느 정도 사양이면 충분한지, 휴대성을 어디까지 포기할 수 있는지 계속 비교했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 Ollama 같은 로컬 AI까지 생각하면서 RTX 5050이 들어간 그램 Pro까지 보게 됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 가격, 무게, 실제로 내가 가장 많이 하는 작업을 다시 생각해보니 결국 &lt;b&gt;LG 그램 17 Ultra 7 구독&lt;/b&gt;으로 결정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최고 사양을 고른 건 아니다. 오히려 내가 매일 사용할 환경에서 무엇이 더 중요한지를 따져본 결과에 가깝다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RTX 5050까지 고민했던 과정은 아래 글에 따로 정리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;a href=&quot;https://nocklock.tistory.com/34&quot;&gt; LG 그램 Pro 17 개발용으로 괜찮을까? AI&amp;middot;Ollama 때문에 RTX 5050까지 고민했다 &lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 RAM과 SSD를 어디까지 가져갈지는 생각보다 더 오래 고민했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;a href=&quot;https://nocklock.tistory.com/38&quot;&gt; 개발자 노트북 RAM 32GB&amp;middot;SSD 1TB면 충분할까? 그램 17 고르며 고민한 기준 &lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</description>
      <category>개발 노트</category>
      <category>2026노트북추천</category>
      <category>개발용노트북</category>
      <category>개발자노트북</category>
      <category>개발자노트북추천</category>
      <category>개발환경</category>
      <category>코딩노트북</category>
      <category>쿠팡파트너스</category>
      <category>프로그래밍노트북</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/33</guid>
      <comments>https://nocklock.tistory.com/33#entry33comment</comments>
      <pubDate>Tue, 22 Sep 2026 09:28:41 +0900</pubDate>
    </item>
    <item>
      <title>서버에 올리면 끝인 줄 알았다 &amp;mdash; Docker를 처음 제대로 써봤다 |  RE:개발자 #11</title>
      <link>https://nocklock.tistory.com/18</link>
      <description>&lt;h3 data-end=&quot;178&quot; data-start=&quot;173&quot; data-ke-size=&quot;size23&quot;&gt;아니었다.&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오전 12_08_15.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tFBMc/dJMcajw5UgJ/NLd5Ti6c5wI4lO35WCF1s0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tFBMc/dJMcajw5UgJ/NLd5Ti6c5wI4lO35WCF1s0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tFBMc/dJMcajw5UgJ/NLd5Ti6c5wI4lO35WCF1s0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtFBMc%2FdJMcajw5UgJ%2FNLd5Ti6c5wI4lO35WCF1s0%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; alt=&quot;Docker&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오전 12_08_15.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;231&quot; data-start=&quot;180&quot; data-ke-size=&quot;size16&quot;&gt;지난 글에서 내 컴퓨터에서만 돌아가던 프로젝트를 다른 사람도 사용할 수 있게 해보려고 했다.&lt;/p&gt;
&lt;p data-end=&quot;251&quot; data-start=&quot;233&quot; data-ke-size=&quot;size16&quot;&gt;그러려면 결국 배포를 해야 했다.&lt;/p&gt;
&lt;p data-end=&quot;268&quot; data-start=&quot;253&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 단순하게 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;311&quot; data-start=&quot;270&quot; data-ke-size=&quot;size16&quot;&gt;서버 하나 정하고,&lt;br /&gt;내 프로젝트 올리고,&lt;br /&gt;실행하면 되는 거 아닌가?&lt;/p&gt;
&lt;p data-end=&quot;378&quot; data-start=&quot;313&quot; data-ke-size=&quot;size16&quot;&gt;회사에서 개발할 때도 배포라는 말을 수도 없이 들었고, 서버에 소스가 올라가서 서비스가 돌아간다는 것도 알고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;440&quot; data-start=&quot;380&quot; data-ke-size=&quot;size16&quot;&gt;그런데 내가 처음부터 만든 프로젝트를 직접 배포하려고 하니까 그 사이에 있는 것들이 하나씩 보이기 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;455&quot; data-start=&quot;442&quot; data-ke-size=&quot;size16&quot;&gt;그리고 생각보다 많았다.&lt;/p&gt;
&lt;hr data-end=&quot;460&quot; data-start=&quot;457&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;484&quot; data-start=&quot;462&quot; data-ke-size=&quot;size26&quot;&gt;Docker라는 이름은 알고 있었다&lt;/h2&gt;
&lt;p data-end=&quot;514&quot; data-start=&quot;486&quot; data-ke-size=&quot;size16&quot;&gt;배포 방법을 알아보다가 다시 Docker를 만났다.&lt;/p&gt;
&lt;p data-end=&quot;523&quot; data-start=&quot;516&quot; data-ke-size=&quot;size16&quot;&gt;Docker.&lt;/p&gt;
&lt;p data-end=&quot;546&quot; data-start=&quot;525&quot; data-ke-size=&quot;size16&quot;&gt;개발하면서 정말 많이 들어본 이름이다.&lt;/p&gt;
&lt;p data-end=&quot;565&quot; data-start=&quot;548&quot; data-ke-size=&quot;size16&quot;&gt;대충 어떤 건지도 알고 있었다.&lt;/p&gt;
&lt;blockquote data-end=&quot;621&quot; data-start=&quot;567&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;621&quot; data-start=&quot;569&quot; data-ke-size=&quot;size16&quot;&gt;실행에 필요한 환경까지 묶어서&lt;br /&gt;어디서 실행하든 비슷한 환경을 만들 수 있게 해주는 것.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;638&quot; data-start=&quot;623&quot; data-ke-size=&quot;size16&quot;&gt;이 정도로 이해하고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;651&quot; data-start=&quot;640&quot; data-ke-size=&quot;size16&quot;&gt;틀린 말은 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;686&quot; data-start=&quot;653&quot; data-ke-size=&quot;size16&quot;&gt;문제는 내가 &lt;b&gt;직접 써본 적이 거의 없었다는 것&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p data-end=&quot;760&quot; data-start=&quot;688&quot; data-ke-size=&quot;size16&quot;&gt;JDK 버전이 다를 수도 있고,&lt;br /&gt;운영체제가 다를 수도 있고,&lt;br /&gt;내 컴퓨터에서는 당연히 있던 설정이 서버에는 없을 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;769&quot; data-start=&quot;762&quot; data-ke-size=&quot;size16&quot;&gt;그동안은 그냥&lt;/p&gt;
&lt;blockquote data-end=&quot;788&quot; data-start=&quot;771&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;788&quot; data-start=&quot;773&quot; data-ke-size=&quot;size16&quot;&gt;&quot;내 컴퓨터에서는 되는데?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;802&quot; data-start=&quot;790&quot; data-ke-size=&quot;size16&quot;&gt;라고 말할 수 있었다.&lt;/p&gt;
&lt;p data-end=&quot;831&quot; data-start=&quot;804&quot; data-ke-size=&quot;size16&quot;&gt;배포하려고 하니까 그 말이 아무 의미가 없어졌다.&lt;/p&gt;
&lt;p data-end=&quot;888&quot; data-start=&quot;833&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터에서 잘 실행되는 게 중요한 게 아니라, &lt;b&gt;내 컴퓨터가 아닌 곳에서도 실행돼야 했다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;920&quot; data-start=&quot;890&quot; data-ke-size=&quot;size16&quot;&gt;그제야 Docker가 왜 필요한지 조금 다르게 보였다.&lt;/p&gt;
&lt;hr data-end=&quot;925&quot; data-start=&quot;922&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;948&quot; data-start=&quot;927&quot; data-ke-size=&quot;size26&quot;&gt;그런데 갑자기 Linux가 나왔다&lt;/h2&gt;
&lt;p data-end=&quot;991&quot; data-start=&quot;950&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 준비하고 배포를 진행하다 보니 이번에는 Linux가 나왔다.&lt;/p&gt;
&lt;p data-end=&quot;1014&quot; data-start=&quot;993&quot; data-ke-size=&quot;size16&quot;&gt;나는 Windows에서 개발하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;1073&quot; data-start=&quot;1016&quot; data-ke-size=&quot;size16&quot;&gt;IntelliJ를 켜고, PowerShell을 열고, Spring Boot를 실행하는 환경이 익숙하다.&lt;/p&gt;
&lt;p data-end=&quot;1128&quot; data-start=&quot;1075&quot; data-ke-size=&quot;size16&quot;&gt;그런데 배포 환경으로 넘어가니 내가 평소 사용하던 Windows 기준으로만 생각할 수가 없었다.&lt;/p&gt;
&lt;p data-end=&quot;1155&quot; data-start=&quot;1130&quot; data-ke-size=&quot;size16&quot;&gt;결국 WSL을 통해 Ubuntu까지 들어갔다.&lt;/p&gt;
&lt;p data-end=&quot;1179&quot; data-start=&quot;1157&quot; data-ke-size=&quot;size16&quot;&gt;솔직히 여기서 잠깐 이런 생각이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;1242&quot; data-start=&quot;1181&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;나는 분명 Spring Boot 프로젝트를 배포하려고 했는데 왜 갑자기 Linux 터미널을 보고 있지?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1256&quot; data-start=&quot;1244&quot; data-ke-size=&quot;size16&quot;&gt;그래도 하나씩 해봤다.&lt;/p&gt;
&lt;p data-end=&quot;1281&quot; data-start=&quot;1258&quot; data-ke-size=&quot;size16&quot;&gt;Ubuntu에서 프로젝트 폴더로 이동하고,&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;gradle&quot;&gt;&lt;code&gt;cd /mnt/d/dev/project/wanted-ai-champ&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1347&quot; data-start=&quot;1334&quot; data-ke-size=&quot;size16&quot;&gt;Git 상태도 확인했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1387&quot; data-start=&quot;1373&quot; data-ke-size=&quot;size16&quot;&gt;그런데 또 문제가 생겼다.&lt;/p&gt;
&lt;hr data-end=&quot;1392&quot; data-start=&quot;1389&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1417&quot; data-start=&quot;1394&quot; data-ke-size=&quot;size26&quot;&gt;갑자기 파일이 전부 수정됐다고 나왔다&lt;/h2&gt;
&lt;p data-end=&quot;1447&quot; data-start=&quot;1419&quot; data-ke-size=&quot;size16&quot;&gt;git status를 확인했는데 순간 당황했다.&lt;/p&gt;
&lt;p data-end=&quot;1484&quot; data-start=&quot;1449&quot; data-ke-size=&quot;size16&quot;&gt;내가 건드린 기억이 없는 파일들까지 수정됐다고 나오기 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;1527&quot; data-start=&quot;1486&quot; data-ke-size=&quot;size16&quot;&gt;Java 파일부터 Gradle 설정, 문서까지 수정된 파일이 한가득이었다.&lt;/p&gt;
&lt;p data-end=&quot;1554&quot; data-start=&quot;1529&quot; data-ke-size=&quot;size16&quot;&gt;배포하려다가 프로젝트를 망가뜨린 건가 싶었다.&lt;/p&gt;
&lt;p data-end=&quot;1580&quot; data-start=&quot;1556&quot; data-ke-size=&quot;size16&quot;&gt;그런데 실제 코드가 전부 바뀐 건 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;1628&quot; data-start=&quot;1582&quot; data-ke-size=&quot;size16&quot;&gt;Windows와 Linux를 오가면서 &lt;b&gt;줄바꿈 방식이 다르게 인식된 문제&lt;/b&gt;였다.&lt;/p&gt;
&lt;p data-end=&quot;1673&quot; data-start=&quot;1630&quot; data-ke-size=&quot;size16&quot;&gt;Windows에서는 보통 CRLF를 사용하고 Linux에서는 LF를 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;1725&quot; data-start=&quot;1675&quot; data-ke-size=&quot;size16&quot;&gt;평소에는 별생각 없이 쓰던 차이인데 Git에서는 파일 전체가 바뀐 것처럼 보일 수 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1749&quot; data-start=&quot;1727&quot; data-ke-size=&quot;size16&quot;&gt;그래서 실제 변경 내용을 다시 확인했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;git diff --ignore-space-at-eol --stat&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1816&quot; data-start=&quot;1802&quot; data-ke-size=&quot;size16&quot;&gt;결과는 생각보다 단순했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;lsl&quot;&gt;&lt;code&gt;.dockerignore | 7 +++++++
railway.toml  | 6 ++++++
2 files changed, 13 insertions(+)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1936&quot; data-start=&quot;1916&quot; data-ke-size=&quot;size16&quot;&gt;수십 개 파일을 건드린 게 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;1966&quot; data-start=&quot;1938&quot; data-ke-size=&quot;size16&quot;&gt;실제로 추가한 건 배포를 위해 만든 파일 정도였다.&lt;/p&gt;
&lt;p data-end=&quot;1980&quot; data-start=&quot;1968&quot; data-ke-size=&quot;size16&quot;&gt;그제야 조금 안심했다.&lt;/p&gt;
&lt;p data-end=&quot;2001&quot; data-start=&quot;1982&quot; data-ke-size=&quot;size16&quot;&gt;그리고 동시에 이런 생각도 들었다.&lt;/p&gt;
&lt;p data-end=&quot;2037&quot; data-start=&quot;2003&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개발 환경이 바뀐다는 게 생각보다 많은 걸 바꾸는구나.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;2042&quot; data-start=&quot;2039&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2080&quot; data-start=&quot;2044&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;.dockerignore도 처음에는 별거 아닌 줄 알았다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-end=&quot;2123&quot; data-start=&quot;2082&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 사용하면서 .dockerignore라는 파일도 만들었다.&lt;/p&gt;
&lt;p data-end=&quot;2151&quot; data-start=&quot;2125&quot; data-ke-size=&quot;size16&quot;&gt;이름만 보면 .gitignore랑 비슷하다.&lt;/p&gt;
&lt;p data-end=&quot;2202&quot; data-start=&quot;2153&quot; data-ke-size=&quot;size16&quot;&gt;Docker 이미지를 만들 때 굳이 포함하지 않아도 되는 파일들을 제외하는 역할을 한다.&lt;/p&gt;
&lt;p data-end=&quot;2227&quot; data-start=&quot;2204&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 이런 파일이 왜 필요한가 싶었다.&lt;/p&gt;
&lt;p data-end=&quot;2254&quot; data-start=&quot;2229&quot; data-ke-size=&quot;size16&quot;&gt;그냥 프로젝트 전체를 넣으면 되는 거 아닌가?&lt;/p&gt;
&lt;p data-end=&quot;2323&quot; data-start=&quot;2256&quot; data-ke-size=&quot;size16&quot;&gt;그런데 생각해보면 로컬에서 생성된 빌드 결과물이나 IDE 설정 같은 것까지 전부 Docker 빌드에 들어갈 이유가 없다.&lt;/p&gt;
&lt;p data-end=&quot;2344&quot; data-start=&quot;2325&quot; data-ke-size=&quot;size16&quot;&gt;.gitignore가 Git에게&lt;/p&gt;
&lt;blockquote data-end=&quot;2361&quot; data-start=&quot;2346&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2361&quot; data-start=&quot;2348&quot; data-ke-size=&quot;size16&quot;&gt;이건 굳이 관리하지 마.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2372&quot; data-start=&quot;2363&quot; data-ke-size=&quot;size16&quot;&gt;라고 알려준다면,&lt;/p&gt;
&lt;p data-end=&quot;2399&quot; data-start=&quot;2374&quot; data-ke-size=&quot;size16&quot;&gt;.dockerignore는 Docker에게&lt;/p&gt;
&lt;blockquote data-end=&quot;2422&quot; data-start=&quot;2401&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2422&quot; data-start=&quot;2403&quot; data-ke-size=&quot;size16&quot;&gt;이건 이미지 만들 때 가져가지 마.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2437&quot; data-start=&quot;2424&quot; data-ke-size=&quot;size16&quot;&gt;라고 알려주는 셈이었다.&lt;/p&gt;
&lt;p data-end=&quot;2485&quot; data-start=&quot;2439&quot; data-ke-size=&quot;size16&quot;&gt;하나씩 직접 써보니까 예전에 이름만 알고 넘어갔던 것들이 조금씩 연결되기 시작했다.&lt;/p&gt;
&lt;hr data-end=&quot;2490&quot; data-start=&quot;2487&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2525&quot; data-start=&quot;2492&quot; data-ke-size=&quot;size26&quot;&gt;Docker를 배운 게 아니라, 왜 쓰는지를 알게 됐다&lt;/h2&gt;
&lt;p data-end=&quot;2558&quot; data-start=&quot;2527&quot; data-ke-size=&quot;size16&quot;&gt;사실 아직 Docker를 잘 안다고 말할 수준은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;2608&quot; data-start=&quot;2560&quot; data-ke-size=&quot;size16&quot;&gt;명령어를 자유롭게 쓰는 것도 아니고, Dockerfile을 능숙하게 설계할 수도 없다.&lt;/p&gt;
&lt;p data-end=&quot;2630&quot; data-start=&quot;2610&quot; data-ke-size=&quot;size16&quot;&gt;그런데 예전과 달라진 건 하나 있다.&lt;/p&gt;
&lt;p data-end=&quot;2653&quot; data-start=&quot;2632&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;왜 이걸 쓰는지는 알 것 같다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2676&quot; data-start=&quot;2655&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 Docker를 공부하려고 하면&lt;/p&gt;
&lt;p data-end=&quot;2704&quot; data-start=&quot;2678&quot; data-ke-size=&quot;size16&quot;&gt;이미지,&lt;br /&gt;컨테이너,&lt;br /&gt;Dockerfile,&lt;/p&gt;
&lt;p data-end=&quot;2722&quot; data-start=&quot;2706&quot; data-ke-size=&quot;size16&quot;&gt;이런 단어부터 외우려고 했다.&lt;/p&gt;
&lt;p data-end=&quot;2734&quot; data-start=&quot;2724&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 반대였다.&lt;/p&gt;
&lt;p data-end=&quot;2799&quot; data-start=&quot;2736&quot; data-ke-size=&quot;size16&quot;&gt;내 프로젝트를 다른 컴퓨터에서 실행해야 하는 문제가 먼저 생겼고, 그 문제를 해결하다 보니 Docker가 나왔다.&lt;/p&gt;
&lt;p data-end=&quot;2830&quot; data-start=&quot;2801&quot; data-ke-size=&quot;size16&quot;&gt;그래서인지 예전에 공부할 때보다 훨씬 이해가 빨랐다.&lt;/p&gt;
&lt;hr data-end=&quot;2835&quot; data-start=&quot;2832&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2854&quot; data-start=&quot;2837&quot; data-ke-size=&quot;size26&quot;&gt;아직 배포는 끝나지 않았다&lt;/h2&gt;
&lt;p data-end=&quot;2896&quot; data-start=&quot;2856&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 준비하고 Linux 환경까지 들어갔다고 끝난 건 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;2919&quot; data-start=&quot;2898&quot; data-ke-size=&quot;size16&quot;&gt;오히려 이제 진짜 배포가 남아 있었다.&lt;/p&gt;
&lt;p data-end=&quot;2947&quot; data-start=&quot;2921&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터에서만 열리던 화면을 인터넷에 올리고,&lt;/p&gt;
&lt;p data-end=&quot;2973&quot; data-start=&quot;2949&quot; data-ke-size=&quot;size16&quot;&gt;localhost가 아닌 주소를 만들고,&lt;/p&gt;
&lt;p data-end=&quot;3015&quot; data-start=&quot;2975&quot; data-ke-size=&quot;size16&quot;&gt;그 주소를 다른 사람에게 보내도 정말 같은 화면이 뜨는지 확인해야 했다.&lt;/p&gt;
&lt;p data-end=&quot;3026&quot; data-start=&quot;3017&quot; data-ke-size=&quot;size16&quot;&gt;그리고 다음 날,&lt;/p&gt;
&lt;p data-end=&quot;3079&quot; data-start=&quot;3028&quot; data-ke-size=&quot;size16&quot;&gt;브라우저 주소창에서 처음으로 localhost가 아닌 주소로 내가 만든 서비스를 열었다.&lt;/p&gt;
&lt;p data-end=&quot;3098&quot; data-start=&quot;3081&quot; data-ke-size=&quot;size16&quot;&gt;그 순간은 생각보다 꽤 좋았다.&lt;/p&gt;</description>
      <category>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/18</guid>
      <comments>https://nocklock.tistory.com/18#entry18comment</comments>
      <pubDate>Tue, 22 Sep 2026 08:08:43 +0900</pubDate>
    </item>
    <item>
      <title>ChatGPT와 Claude를 며칠 동안 개발에 붙여놓고 생긴 변화</title>
      <link>https://nocklock.tistory.com/17</link>
      <description>&lt;p data-end=&quot;210&quot; data-start=&quot;160&quot; data-ke-size=&quot;size16&quot;&gt;요즘 프로젝트를 진행하면서 ChatGPT와 Claude를 거의 계속 켜놓고 개발하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;227&quot; data-start=&quot;212&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 19일 오전 09_26_49.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b16FlT/dJMcaatmUwx/e2yy9d7bPhowwSOplTVJdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b16FlT/dJMcaatmUwx/e2yy9d7bPhowwSOplTVJdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b16FlT/dJMcaatmUwx/e2yy9d7bPhowwSOplTVJdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb16FlT%2FdJMcaatmUwx%2Fe2yy9d7bPhowwSOplTVJdk%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;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 19일 오전 09_26_49.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;304&quot; data-start=&quot;229&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;코드가 이상하면 코드를 보여주고,&lt;br /&gt;어떻게 만들어야 할지 모르겠으면 그냥 물어봤다.&lt;/p&gt;
&lt;p data-end=&quot;304&quot; data-start=&quot;229&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;354&quot; data-start=&quot;306&quot; data-ke-size=&quot;size16&quot;&gt;그런데 며칠 동안 프로젝트 하나를 처음부터 계속 같이 만들어보니 조금 달라진 게 있다.&lt;/p&gt;
&lt;p data-end=&quot;354&quot; data-start=&quot;306&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;388&quot; data-start=&quot;356&quot; data-ke-size=&quot;size16&quot;&gt;AI가 달라졌다기보다는 내가 AI를 쓰는 방식이 달라졌다.&lt;/p&gt;
&lt;h2 data-end=&quot;412&quot; data-start=&quot;390&quot; data-ke-size=&quot;size26&quot;&gt;처음에는 그냥 &amp;ldquo;왜 안 되지?&amp;rdquo;였다&lt;/h2&gt;
&lt;p data-end=&quot;432&quot; data-start=&quot;414&quot; data-ke-size=&quot;size16&quot;&gt;개발하다 막히면 질문은 단순했다.&lt;/p&gt;
&lt;p data-end=&quot;445&quot; data-start=&quot;434&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이거 왜 안 돼?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;468&quot; data-start=&quot;447&quot; data-ke-size=&quot;size16&quot;&gt;에러 메시지를 붙여넣고 답을 기다렸다.&lt;/p&gt;
&lt;p data-end=&quot;504&quot; data-start=&quot;470&quot; data-ke-size=&quot;size16&quot;&gt;AI가 코드를 만들어주면 그대로 넣어보고, 실행되면 넘어갔다.&lt;/p&gt;
&lt;p data-end=&quot;504&quot; data-start=&quot;470&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;514&quot; data-start=&quot;506&quot; data-ke-size=&quot;size16&quot;&gt;확실히 빠르다.&lt;/p&gt;
&lt;p data-end=&quot;514&quot; data-start=&quot;506&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;603&quot; data-start=&quot;516&quot; data-ke-size=&quot;size16&quot;&gt;예전 같았으면 검색해서 비슷한 사례를 찾고, Stack Overflow나 블로그 몇 개를 열어놓고 하나씩 비교했을 일도 몇 분 안에 해결되는 경우가 있었다.&lt;/p&gt;
&lt;p data-end=&quot;620&quot; data-start=&quot;605&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 그게 제일 좋았다.&lt;/p&gt;
&lt;p data-end=&quot;649&quot; data-start=&quot;622&quot; data-ke-size=&quot;size16&quot;&gt;그런데 프로젝트가 조금씩 커지니까 문제가 생겼다.&lt;/p&gt;
&lt;p data-end=&quot;718&quot; data-start=&quot;651&quot; data-ke-size=&quot;size16&quot;&gt;AI가 알려준 코드가 틀린 건 아닌데,&lt;/p&gt;
&lt;p data-end=&quot;718&quot; data-start=&quot;651&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;내가 지금 만들고 있는 프로젝트에는 맞지 않는 경우가 생기기 시작했다.&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;744&quot; data-start=&quot;720&quot; data-ke-size=&quot;size26&quot;&gt;이제는 질문하기 전에 상황부터 설명한다&lt;/h2&gt;
&lt;p data-end=&quot;797&quot; data-start=&quot;746&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 이미 정상적으로 돌아가는 기능이 있는데 새로운 기능 하나를 추가하고 싶다고 하자.&lt;/p&gt;
&lt;p data-end=&quot;821&quot; data-start=&quot;799&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 그냥 이렇게 물어봤을 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;843&quot; data-start=&quot;823&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이 기능 추가하는 코드 만들어줘.&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;856&quot; data-start=&quot;845&quot; data-ke-size=&quot;size16&quot;&gt;지금은 조금 다르다.&lt;/p&gt;
&lt;p data-end=&quot;946&quot; data-start=&quot;858&quot; data-ke-size=&quot;size16&quot;&gt;현재 어떤 구조인지,&lt;br /&gt;어디까지 정상 동작하고 있는지,&lt;br /&gt;이번에 바꾸고 싶은 부분이 어디인지,&lt;br /&gt;그리고 건드리면 안 되는 부분이 무엇인지부터 이야기한다.&lt;/p&gt;
&lt;p data-end=&quot;980&quot; data-start=&quot;948&quot; data-ke-size=&quot;size16&quot;&gt;실제로 요즘 내가 가장 자주 하는 말 중 하나가 이것이다.&lt;/p&gt;
&lt;p data-end=&quot;1018&quot; data-start=&quot;982&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;지금 이 부분은 정상 동작하고 있으니까 건드리지 말자.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1040&quot; data-start=&quot;1020&quot; data-ke-size=&quot;size16&quot;&gt;이 말을 자주 하게 될 줄은 몰랐다.&lt;/p&gt;
&lt;p data-end=&quot;1067&quot; data-start=&quot;1042&quot; data-ke-size=&quot;size16&quot;&gt;AI는 내가 보여준 정보 안에서 답을 만든다.&lt;/p&gt;
&lt;p data-end=&quot;1148&quot; data-start=&quot;1069&quot; data-ke-size=&quot;size16&quot;&gt;그러다 보니 내가 상황을 제대로 설명하지 않으면, 굳이 수정할 필요가 없는 코드까지 바뀌거나 이미 해결했던 문제가 다시 생기는 경우도 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1196&quot; data-start=&quot;1150&quot; data-ke-size=&quot;size16&quot;&gt;결국 AI에게 질문을 잘하려면 내가 내 프로젝트를 어느 정도 이해하고 있어야 했다.&lt;/p&gt;
&lt;h2 data-end=&quot;1229&quot; data-start=&quot;1198&quot; data-ke-size=&quot;size26&quot;&gt;ChatGPT와 Claude의 역할도 조금 달라졌다&lt;/h2&gt;
&lt;p data-end=&quot;1250&quot; data-start=&quot;1231&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 둘 다 비슷하게 사용했다.&lt;/p&gt;
&lt;p data-end=&quot;1282&quot; data-start=&quot;1252&quot; data-ke-size=&quot;size16&quot;&gt;코드 물어보고, 오류 물어보고, 설명을 듣는 식이었다.&lt;/p&gt;
&lt;p data-end=&quot;1317&quot; data-start=&quot;1284&quot; data-ke-size=&quot;size16&quot;&gt;그런데 계속 사용하다 보니 자연스럽게 역할이 조금 나뉘었다.&lt;/p&gt;
&lt;p data-end=&quot;1349&quot; data-start=&quot;1319&quot; data-ke-size=&quot;size16&quot;&gt;ChatGPT에는 프로젝트 전체 방향을 많이 물어봤다.&lt;/p&gt;
&lt;p data-end=&quot;1420&quot; data-start=&quot;1351&quot; data-ke-size=&quot;size16&quot;&gt;지금 기능을 더 추가하는 게 맞는지,&lt;br /&gt;프론트를 먼저 붙이는 게 맞는지,&lt;br /&gt;여기서 배포로 넘어가도 되는지 같은 것들이다.&lt;/p&gt;
&lt;p data-end=&quot;1462&quot; data-start=&quot;1422&quot; data-ke-size=&quot;size16&quot;&gt;개발하다 보면 이상하게 코드보다 이런 판단에서 더 오래 막힐 때가 있다.&lt;/p&gt;
&lt;p data-end=&quot;1478&quot; data-start=&quot;1464&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이걸 지금 해야 하나?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;1497&quot; data-start=&quot;1480&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;아니면 일단 넘어가야 하나?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;1527&quot; data-start=&quot;1499&quot; data-ke-size=&quot;size16&quot;&gt;혼자 개발하면 이런 판단을 계속 혼자 내려야 한다.&lt;/p&gt;
&lt;p data-end=&quot;1573&quot; data-start=&quot;1529&quot; data-ke-size=&quot;size16&quot;&gt;그럴 때 상황을 한번 정리해서 이야기하고 답을 듣는 것만으로도 꽤 도움이 됐다.&lt;/p&gt;
&lt;p data-end=&quot;1604&quot; data-start=&quot;1575&quot; data-ke-size=&quot;size16&quot;&gt;Claude는 코드 단위로 같이 보는 경우가 많았다.&lt;/p&gt;
&lt;p data-end=&quot;1653&quot; data-start=&quot;1606&quot; data-ke-size=&quot;size16&quot;&gt;현재 파일을 보여주고, 기존 구조를 최대한 유지하면서 필요한 부분만 수정하는 식이다.&lt;/p&gt;
&lt;p data-end=&quot;1689&quot; data-start=&quot;1655&quot; data-ke-size=&quot;size16&quot;&gt;물론 이건 둘 중 하나가 반드시 더 잘한다는 이야기는 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1732&quot; data-start=&quot;1691&quot; data-ke-size=&quot;size16&quot;&gt;그냥 며칠 동안 같이 개발하다 보니 자연스럽게 내가 그렇게 사용하게 됐다.&lt;/p&gt;
&lt;h2 data-end=&quot;1762&quot; data-start=&quot;1734&quot; data-ke-size=&quot;size26&quot;&gt;AI가 코드를 만들어주니까 개발이 쉬워졌을까?&lt;/h2&gt;
&lt;p data-end=&quot;1775&quot; data-start=&quot;1764&quot; data-ke-size=&quot;size16&quot;&gt;이건 조금 애매하다.&lt;/p&gt;
&lt;p data-end=&quot;1786&quot; data-start=&quot;1777&quot; data-ke-size=&quot;size16&quot;&gt;확실히 빨라졌다.&lt;/p&gt;
&lt;p data-end=&quot;1837&quot; data-start=&quot;1788&quot; data-ke-size=&quot;size16&quot;&gt;모르는 문법을 찾는 시간도 줄었고,&lt;br /&gt;처음 접하는 기술에 들어가는 부담도 많이 줄었다.&lt;/p&gt;
&lt;p data-end=&quot;1902&quot; data-start=&quot;1839&quot; data-ke-size=&quot;size16&quot;&gt;이번에 배포를 준비하면서 Linux나 Ubuntu를 다시 보고, 처음 보는 설정 파일을 만졌을 때도 마찬가지였다.&lt;/p&gt;
&lt;p data-end=&quot;1941&quot; data-start=&quot;1904&quot; data-ke-size=&quot;size16&quot;&gt;예전 같았으면 검색 결과 여러 개를 비교하면서 한참 헤맸을 것이다.&lt;/p&gt;
&lt;p data-end=&quot;1959&quot; data-start=&quot;1943&quot; data-ke-size=&quot;size16&quot;&gt;지금은 바로 물어볼 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2012&quot; data-start=&quot;1961&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이상하게도 프로젝트가 진행될수록 오히려 내가 알아야 할 게 더 많다는 생각이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;2057&quot; data-start=&quot;2014&quot; data-ke-size=&quot;size16&quot;&gt;AI가 코드를 써주는 것과&lt;br /&gt;그 코드가 맞는지 판단하는 것은 다른 일이었다.&lt;/p&gt;
&lt;p data-end=&quot;2135&quot; data-start=&quot;2059&quot; data-ke-size=&quot;size16&quot;&gt;코드를 한 줄도 몰라도 프로그램을 만들 수 있다는 이야기가 종종 나오지만, 적어도 내가 며칠 동안 직접 개발하면서 느낀 건 조금 달랐다.&lt;/p&gt;
&lt;p data-end=&quot;2177&quot; data-start=&quot;2137&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AI가 써준 코드를 제대로 쓰려면 결국 내가 코드를 알아야 했다.&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;2202&quot; data-start=&quot;2179&quot; data-ke-size=&quot;size26&quot;&gt;가장 무서운 건 틀린 코드가 아니었다&lt;/h2&gt;
&lt;p data-end=&quot;2221&quot; data-start=&quot;2204&quot; data-ke-size=&quot;size16&quot;&gt;틀린 코드는 오히려 찾기 쉽다.&lt;/p&gt;
&lt;p data-end=&quot;2235&quot; data-start=&quot;2223&quot; data-ke-size=&quot;size16&quot;&gt;실행하면 에러가 난다.&lt;/p&gt;
&lt;p data-end=&quot;2257&quot; data-start=&quot;2237&quot; data-ke-size=&quot;size16&quot;&gt;문제는 그럴듯하게 돌아가는 코드였다.&lt;/p&gt;
&lt;p data-end=&quot;2278&quot; data-start=&quot;2259&quot; data-ke-size=&quot;size16&quot;&gt;프로그램도 실행되고 결과도 나온다.&lt;/p&gt;
&lt;p data-end=&quot;2346&quot; data-start=&quot;2280&quot; data-ke-size=&quot;size16&quot;&gt;그런데 기존 구조와 어울리지 않거나, 필요 이상으로 복잡하거나, 나중에 문제가 될 수 있는 코드라면 이야기가 달라진다.&lt;/p&gt;
&lt;p data-end=&quot;2368&quot; data-start=&quot;2348&quot; data-ke-size=&quot;size16&quot;&gt;AI는 굉장히 자신 있게 답을 준다.&lt;/p&gt;
&lt;p data-end=&quot;2412&quot; data-start=&quot;2370&quot; data-ke-size=&quot;size16&quot;&gt;그래서 처음에는 답이 나오면 나도 모르게 &amp;ldquo;이게 맞겠지&amp;rdquo;라고 생각하게 된다.&lt;/p&gt;
&lt;p data-end=&quot;2451&quot; data-start=&quot;2414&quot; data-ke-size=&quot;size16&quot;&gt;며칠 동안 계속 사용하면서 가장 많이 바뀐 부분이 이것인 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;2457&quot; data-start=&quot;2453&quot; data-ke-size=&quot;size16&quot;&gt;예전에는&lt;/p&gt;
&lt;p data-end=&quot;2479&quot; data-start=&quot;2459&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AI가 답을 주면 실행해봤다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2484&quot; data-start=&quot;2481&quot; data-ke-size=&quot;size16&quot;&gt;지금은&lt;/p&gt;
&lt;p data-end=&quot;2512&quot; data-start=&quot;2486&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AI가 답을 주면 내가 먼저 한번 본다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2534&quot; data-start=&quot;2514&quot; data-ke-size=&quot;size16&quot;&gt;작은 차이인데 개발할 때는 꽤 컸다.&lt;/p&gt;
&lt;h2 data-end=&quot;2561&quot; data-start=&quot;2536&quot; data-ke-size=&quot;size26&quot;&gt;대신 혼자 개발한다는 느낌은 많이 줄었다&lt;/h2&gt;
&lt;p data-end=&quot;2593&quot; data-start=&quot;2563&quot; data-ke-size=&quot;size16&quot;&gt;그래도 AI를 계속 사용하는 가장 큰 이유는 분명하다.&lt;/p&gt;
&lt;p data-end=&quot;2619&quot; data-start=&quot;2595&quot; data-ke-size=&quot;size16&quot;&gt;혼자 개발할 때 막히는 시간이 많이 줄었다.&lt;/p&gt;
&lt;p data-end=&quot;2653&quot; data-start=&quot;2621&quot; data-ke-size=&quot;size16&quot;&gt;특히 오랜만에 다시 개발을 시작한 나에게는 이게 꽤 컸다.&lt;/p&gt;
&lt;p data-end=&quot;2683&quot; data-start=&quot;2655&quot; data-ke-size=&quot;size16&quot;&gt;기억이 안 나는 것도 많고, 처음 보는 것도 많다.&lt;/p&gt;
&lt;p data-end=&quot;2768&quot; data-start=&quot;2685&quot; data-ke-size=&quot;size16&quot;&gt;예전 같았으면 하나 막힐 때마다 검색을 시작하고, 그 과정에서 또 모르는 단어가 나오고, 다시 검색하다가 처음 뭘 하려고 했는지 잊는 경우도 있었다.&lt;/p&gt;
&lt;p data-end=&quot;2793&quot; data-start=&quot;2770&quot; data-ke-size=&quot;size16&quot;&gt;지금은 그 자리에서 바로 질문할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2817&quot; data-start=&quot;2795&quot; data-ke-size=&quot;size16&quot;&gt;그래서 개발을 잘하게 만들어준다기보다는,&lt;/p&gt;
&lt;p data-end=&quot;2863&quot; data-start=&quot;2819&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개발을 계속할 수 있게 만들어주는 도구&lt;/b&gt;에 조금 더 가깝다는 생각이 든다.&lt;/p&gt;
&lt;h2 data-end=&quot;2877&quot; data-start=&quot;2865&quot; data-ke-size=&quot;size26&quot;&gt;며칠 써보고 나니&lt;/h2&gt;
&lt;p data-end=&quot;2909&quot; data-start=&quot;2879&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 AI가 코드를 대신 써주는 게 가장 신기했다.&lt;/p&gt;
&lt;p data-end=&quot;2937&quot; data-start=&quot;2911&quot; data-ke-size=&quot;size16&quot;&gt;지금은 그것보다 다른 부분이 더 크게 느껴진다.&lt;/p&gt;
&lt;p data-end=&quot;3006&quot; data-start=&quot;2939&quot; data-ke-size=&quot;size16&quot;&gt;내 생각을 정리하고,&lt;br /&gt;막힌 부분을 설명하고,&lt;br /&gt;다음에 뭘 해야 할지 확인하고,&lt;br /&gt;내가 놓친 부분을 다시 보는 것.&lt;/p&gt;
&lt;p data-end=&quot;3054&quot; data-start=&quot;3008&quot; data-ke-size=&quot;size16&quot;&gt;개발하면서 AI와 대화를 많이 할수록 오히려 내가 무엇을 모르는지가 더 잘 보였다.&lt;/p&gt;
&lt;p data-end=&quot;3076&quot; data-start=&quot;3056&quot; data-ke-size=&quot;size16&quot;&gt;그리고 질문도 조금씩 달라지고 있다&lt;/p&gt;
&lt;p data-end=&quot;3076&quot; data-start=&quot;3056&quot; data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;
&lt;p data-end=&quot;3088&quot; data-start=&quot;3078&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이거 만들어줘.&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;3092&quot; data-start=&quot;3090&quot; data-ke-size=&quot;size16&quot;&gt;에서&lt;/p&gt;
&lt;p data-end=&quot;3092&quot; data-start=&quot;3090&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3115&quot; data-start=&quot;3094&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;내가 지금 이렇게 이해했는데 맞나?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;3119&quot; data-start=&quot;3117&quot; data-ke-size=&quot;size16&quot;&gt;로.&lt;/p&gt;
&lt;p data-end=&quot;3119&quot; data-start=&quot;3117&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3142&quot; data-start=&quot;3121&quot; data-ke-size=&quot;size16&quot;&gt;아마 이 차이가 생각보다 큰 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;3176&quot; data-start=&quot;3144&quot; data-ke-size=&quot;size16&quot;&gt;AI 덕분에 개발이 쉬워졌냐고 묻는다면 아직 잘 모르겠다.&lt;/p&gt;
&lt;p data-end=&quot;3192&quot; data-start=&quot;3178&quot; data-ke-size=&quot;size16&quot;&gt;다만 한 가지는 확실하다.&lt;/p&gt;
&lt;p data-end=&quot;3221&quot; data-start=&quot;3194&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예전보다 훨씬 덜 막히면서 개발하고 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;3246&quot; data-start=&quot;3223&quot; data-ke-size=&quot;size16&quot;&gt;그리고 지금의 나에게는 그게 꽤 중요하다.&lt;/p&gt;</description>
      <category>AI TOOLS</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/17</guid>
      <comments>https://nocklock.tistory.com/17#entry17comment</comments>
      <pubDate>Mon, 21 Sep 2026 13:27:16 +0900</pubDate>
    </item>
    <item>
      <title>내 컴퓨터에서는 잘 되는데, 다른 사람도 쓸 수 있어야 했다 | RE:개발자 #10</title>
      <link>https://nocklock.tistory.com/16</link>
      <description>&lt;p data-end=&quot;201&quot; data-start=&quot;173&quot; data-ke-size=&quot;size16&quot;&gt;음에는 프로그램이 실행되는 것만으로도 꽤 기뻤다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 19일 오전 09_21_25.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uAAbd/dJMcaaz8jQr/4Y7XmXNWcIH5wsk80zAgN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uAAbd/dJMcaaz8jQr/4Y7XmXNWcIH5wsk80zAgN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uAAbd/dJMcaaz8jQr/4Y7XmXNWcIH5wsk80zAgN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuAAbd%2FdJMcaaz8jQr%2F4Y7XmXNWcIH5wsk80zAgN1%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; alt=&quot;deploy start&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 19일 오전 09_21_25.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;267&quot; data-start=&quot;203&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot를 실행하고&lt;br /&gt;브라우저에서 화면이 뜨고&lt;br /&gt;사진을 올리면 내가 만든 기능들이 실제로 동작했다.&lt;/p&gt;
&lt;p data-end=&quot;301&quot; data-start=&quot;269&quot; data-ke-size=&quot;size16&quot;&gt;프론트엔드까지 붙이고 테스트하면서 오류도 꽤 많이 잡았다.&lt;/p&gt;
&lt;p data-end=&quot;343&quot; data-start=&quot;303&quot; data-ke-size=&quot;size16&quot;&gt;이쯤 되니까 처음 만들기 시작했을 때와 비교하면 제법 서비스처럼 보였다.&lt;/p&gt;
&lt;p data-end=&quot;362&quot; data-start=&quot;345&quot; data-ke-size=&quot;size16&quot;&gt;그런데 한 가지 문제가 있었다.&lt;/p&gt;
&lt;p data-end=&quot;383&quot; data-start=&quot;364&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이건 내 컴퓨터에서만 된다.&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;408&quot; data-start=&quot;385&quot; data-ke-size=&quot;size26&quot;&gt;localhost 밖으로 나가야 했다&lt;/h2&gt;
&lt;p data-end=&quot;437&quot; data-start=&quot;410&quot; data-ke-size=&quot;size16&quot;&gt;개발할 때 너무 자연스럽게 사용하던 주소가 있다.&lt;/p&gt;
&lt;p data-end=&quot;450&quot; data-start=&quot;439&quot; data-ke-size=&quot;size16&quot;&gt;localhost&lt;/p&gt;
&lt;p data-end=&quot;495&quot; data-start=&quot;452&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터에서 서버를 실행하고 내가 접속해서 테스트할 때는 아무 문제가 없다.&lt;/p&gt;
&lt;p data-end=&quot;538&quot; data-start=&quot;497&quot; data-ke-size=&quot;size16&quot;&gt;그런데 생각해보니 다른 사람이 내 프로젝트를 사용하려면 이야기가 달라진다.&lt;/p&gt;
&lt;p data-end=&quot;579&quot; data-start=&quot;540&quot; data-ke-size=&quot;size16&quot;&gt;내가 Spring Boot를 켜놓고 주소를 보내준다고 되는 게 아니다.&lt;/p&gt;
&lt;p data-end=&quot;614&quot; data-start=&quot;581&quot; data-ke-size=&quot;size16&quot;&gt;결국 내가 만든 프로그램을 어딘가의 서버에서 실행해야 했다.&lt;/p&gt;
&lt;p data-end=&quot;630&quot; data-start=&quot;616&quot; data-ke-size=&quot;size16&quot;&gt;알고 있던 내용이긴 했다.&lt;/p&gt;
&lt;p data-end=&quot;670&quot; data-start=&quot;632&quot; data-ke-size=&quot;size16&quot;&gt;그런데 직접 만든 프로젝트를 올리려고 하니까 갑자기 느낌이 달라졌다.&lt;/p&gt;
&lt;p data-end=&quot;694&quot; data-start=&quot;672&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;아, 이제 배포를 해야 하는구나.&lt;/b&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;715&quot; data-start=&quot;696&quot; data-ke-size=&quot;size26&quot;&gt;서버에 올리면 끝인 줄 알았다&lt;/h2&gt;
&lt;p data-end=&quot;732&quot; data-start=&quot;717&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 단순하게 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;782&quot; data-start=&quot;734&quot; data-ke-size=&quot;size16&quot;&gt;GitHub에 코드도 있고&lt;br /&gt;Spring Boot도 잘 실행되고&lt;br /&gt;프론트도 있으니까&lt;/p&gt;
&lt;p data-end=&quot;810&quot; data-start=&quot;784&quot; data-ke-size=&quot;size16&quot;&gt;어디 서버 하나 구해서 올리면 되는 거 아닌가?&lt;/p&gt;
&lt;p data-end=&quot;851&quot; data-start=&quot;812&quot; data-ke-size=&quot;size16&quot;&gt;그런데 배포 방법을 찾아보기 시작하자 또 모르는 것들이 줄줄이 나왔다.&lt;/p&gt;
&lt;p data-end=&quot;890&quot; data-start=&quot;853&quot; data-ke-size=&quot;size16&quot;&gt;Linux.&lt;br /&gt;Ubuntu.&lt;br /&gt;Docker.&lt;br /&gt;Railway.&lt;/p&gt;
&lt;p data-end=&quot;903&quot; data-start=&quot;892&quot; data-ke-size=&quot;size16&quot;&gt;이름은 다 들어봤다.&lt;/p&gt;
&lt;p data-end=&quot;949&quot; data-start=&quot;905&quot; data-ke-size=&quot;size16&quot;&gt;문제는 &lt;b&gt;들어본 것과 사용할 줄 아는 것은 완전히 다른 이야기&lt;/b&gt;라는 거였다.&lt;/p&gt;
&lt;p data-end=&quot;978&quot; data-start=&quot;951&quot; data-ke-size=&quot;size16&quot;&gt;나는 지금까지 Windows 환경에서 개발해왔다.&lt;/p&gt;
&lt;p data-end=&quot;1015&quot; data-start=&quot;980&quot; data-ke-size=&quot;size16&quot;&gt;그런데 실제 서버 환경에서는 Linux를 만날 가능성이 높았다.&lt;/p&gt;
&lt;p data-end=&quot;1051&quot; data-start=&quot;1017&quot; data-ke-size=&quot;size16&quot;&gt;결국 배포를 하려다가 갑자기 Ubuntu부터 설치하고 있었다.&lt;/p&gt;
&lt;h2 data-end=&quot;1073&quot; data-start=&quot;1053&quot; data-ke-size=&quot;size26&quot;&gt;배포하러 왔다가 리눅스를 만났다&lt;/h2&gt;
&lt;p data-end=&quot;1108&quot; data-start=&quot;1075&quot; data-ke-size=&quot;size16&quot;&gt;Windows에서 WSL을 설치하고 Ubuntu를 실행했다.&lt;/p&gt;
&lt;p data-end=&quot;1147&quot; data-start=&quot;1110&quot; data-ke-size=&quot;size16&quot;&gt;평소에 보던 PowerShell이나 IntelliJ 터미널이 아니라&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;elixir&quot;&gt;&lt;code&gt;nocklock@DESKTOP:~$&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;510&quot; data-start=&quot;294&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;510&quot; data-start=&quot;294&quot; data-ke-size=&quot;size16&quot;&gt;사실 Linux가 완전히 처음은 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;510&quot; data-start=&quot;294&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;510&quot; data-start=&quot;294&quot; data-ke-size=&quot;size16&quot;&gt;예전 실무에서도 서버에 접속한 적은 있었다. 다만 그때 내가 주로 하던 일은 꽤 한정적이었다. 서버를 내렸다 올리거나, 배포 후 상태를 확인하거나, 로그를 보는 정도였다. 자주 보던 것도 결국 비슷했다. ll로 파일 목록을 보고, tail -f catalina.out으로 로그를 따라가고, 가끔 필요한 파일 위치를 확인하는 정도였다.&lt;/p&gt;
&lt;p data-end=&quot;625&quot; data-start=&quot;512&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;625&quot; data-start=&quot;512&quot; data-ke-size=&quot;size16&quot;&gt;그러니까 Linux를 &amp;ldquo;써봤다&amp;rdquo;고 말할 수는 있었지만, 솔직히 말하면 익숙했던 건 운영이라기보다 확인에 가까웠다.&lt;br /&gt;서비스가 잘 뜨는지 보고, 에러가 나는지 보고, 이상하면 다시 올리고, 그 정도였다.&lt;/p&gt;
&lt;p data-end=&quot;638&quot; data-start=&quot;627&quot; data-ke-size=&quot;size16&quot;&gt;이번은 조금 달랐다.&lt;/p&gt;
&lt;p data-end=&quot;746&quot; data-start=&quot;640&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;746&quot; data-start=&quot;640&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 누가 만들어둔 서버에 들어가서 상태만 보는 게 아니라,&lt;br /&gt;내가 만든 프로젝트를 직접 배포하기 위해 환경을 만지고 있었다.&lt;br /&gt;그래서 같은 터미널 화면인데도 느낌이 좀 다르게 왔다.&lt;/p&gt;
&lt;p data-end=&quot;861&quot; data-start=&quot;748&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;861&quot; data-start=&quot;748&quot; data-ke-size=&quot;size16&quot;&gt;서버 개발자라면서 Linux를 이 정도로만 알고 계속 가도 되나 싶은 생각도 들었다.&lt;br /&gt;지금까지는 필요할 때마다 검색해서 겨우 지나왔는데, 배포를 하려니 이제는 정말 기본은 알아야겠다는 생각이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;959&quot; data-start=&quot;863&quot; data-ke-size=&quot;size16&quot;&gt;그래서 프로젝트 폴더로 이동해서 하나씩 직접 확인하기 시작했다.&lt;br /&gt;예전처럼 막연히 &amp;ldquo;어딘가 되겠지&amp;rdquo;가 아니라, 지금 내가 뭘 보고 있는지 조금은 이해하면서 가보고 싶었다.&lt;/p&gt;
&lt;p data-end=&quot;975&quot; data-start=&quot;961&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면 이런 식이었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;cd /mnt/d/dev/project/wanted-ai-champ
pwd
ll
git status
git diff --ignore-space-at-eol --stat
git log -1 --oneline
cat railway.toml
cat .dockerignore&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1262&quot; data-start=&quot;1140&quot; data-ke-size=&quot;size16&quot;&gt;실제로는 이런 식으로 하나씩 확인하면서 갔다.&lt;br /&gt;프로젝트 위치를 다시 보고, 파일 목록을 확인하고, Git 상태를 보고, 마지막 커밋도 확인했다.&lt;br /&gt;배포를 위해 추가한 설정 파일이 제대로 들어갔는지도 직접 열어봤다.&lt;/p&gt;
&lt;p data-end=&quot;1293&quot; data-start=&quot;1264&quot; data-ke-size=&quot;size16&quot;&gt;예전 실무에서는 대체로 이런 명령어들이 더 익숙했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;cd /usr/local/tomcat/logs
ll
tail -f catalina.out
ps -ef | grep tomcat&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1496&quot; data-start=&quot;1379&quot; data-ke-size=&quot;size16&quot;&gt;그때는 서비스 로그를 보는 게 중심이었다면,&lt;br /&gt;이번에는 그보다 한 단계 앞에 있었다.&lt;br /&gt;프로젝트를 어떤 환경에서 실행할지, 어떤 파일이 배포에 필요한지, 지금 변경된 게 무엇인지부터 내가 직접 챙겨야 했다.&lt;/p&gt;
&lt;p data-end=&quot;1530&quot; data-start=&quot;1498&quot; data-ke-size=&quot;size16&quot;&gt;그래서 더 낯설었고, 동시에 더 개발자다운 느낌도 들었다.&lt;/p&gt;
&lt;hr data-end=&quot;1535&quot; data-start=&quot;1532&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;1590&quot; data-start=&quot;1537&quot; data-ke-size=&quot;size16&quot;&gt;조금 더 &lt;b&gt;명령어가 살아있는 버전&lt;/b&gt;으로 쓰고 싶으면, 아래처럼 더 디테일하게도 갈 수 있어.&lt;/p&gt;
&lt;hr data-end=&quot;1595&quot; data-start=&quot;1592&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;1618&quot; data-start=&quot;1597&quot; data-ke-size=&quot;size16&quot;&gt;같은 화면을 보고 있으니 조금 묘했다.&lt;/p&gt;
&lt;p data-end=&quot;1661&quot; data-start=&quot;1620&quot; data-ke-size=&quot;size16&quot;&gt;사실 Linux가 처음은 아니었다.&lt;br /&gt;그런데 이번에는 분명 조금 달랐다.&lt;/p&gt;
&lt;p data-end=&quot;1858&quot; data-start=&quot;1663&quot; data-ke-size=&quot;size16&quot;&gt;예전에 실무에서 서버를 볼 때 내가 주로 하던 일은 정해져 있었다.&lt;br /&gt;ll로 디렉터리를 훑어보고, tail -f catalina.out으로 로그를 확인하고, 필요하면 프로세스를 보거나 서버를 다시 띄우는 정도였다.&lt;br /&gt;말하자면 Linux를 &amp;ldquo;운영 확인용&amp;rdquo;으로는 접해봤지만, &amp;ldquo;내 프로젝트를 배포하기 위한 환경&amp;rdquo;으로 다뤄본 적은 거의 없었다.&lt;/p&gt;
&lt;p data-end=&quot;1934&quot; data-start=&quot;1860&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번에 Ubuntu 터미널을 열었을 때 익숙하면서도 어색했다.&lt;br /&gt;화면은 비슷한데, 내가 해야 하는 일은 전보다 훨씬 많았다.&lt;/p&gt;
&lt;p data-end=&quot;2022&quot; data-start=&quot;1936&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 누군가 이미 운영 중인 서버에서 로그를 보는 쪽에 가까웠다면,&lt;br /&gt;지금은 내가 만든 프로젝트를 직접 바깥으로 내보내기 위해 하나씩 준비해야 했다.&lt;/p&gt;
&lt;p data-end=&quot;2059&quot; data-start=&quot;2024&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트 폴더로 이동해서 가장 먼저 한 것도 그런 확인들이었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;cd /mnt/d/dev/project/wanted-ai-champ
pwd
ll
git status
git diff --ignore-space-at-eol --stat
git log -1 --oneline&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2277&quot; data-start=&quot;2189&quot; data-ke-size=&quot;size16&quot;&gt;지금 내가 어느 경로에 들어와 있는지 보고,&lt;br /&gt;파일이 제대로 있는지 확인하고,&lt;br /&gt;현재 브랜치 상태와 변경 사항을 보고,&lt;br /&gt;마지막 커밋까지 다시 확인했다.&lt;/p&gt;
&lt;p data-end=&quot;2308&quot; data-start=&quot;2279&quot; data-ke-size=&quot;size16&quot;&gt;그 다음에는 배포를 위해 추가한 파일들도 직접 봤다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;cat .dockerignore
cat railway.toml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2528&quot; data-start=&quot;2358&quot; data-ke-size=&quot;size16&quot;&gt;한 줄 한 줄이 거창한 작업은 아니었다.&lt;br /&gt;그런데 이런 기본적인 확인을 내가 직접 하고 있다는 사실이 좀 다르게 느껴졌다.&lt;br /&gt;예전 같으면 누가 알려준 순서대로 따라가거나, 잘 돌아가는지만 봤을 텐데, 이번에는 적어도 &amp;ldquo;왜 이 파일이 필요한지&amp;rdquo;, &amp;ldquo;지금 무엇이 바뀌었는지&amp;rdquo;를 같이 보려고 했기 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;2560&quot; data-start=&quot;2530&quot; data-ke-size=&quot;size16&quot;&gt;실무 때 익숙했던 Linux는 대체로 이런 느낌이었다.&lt;/p&gt;
&lt;h2 data-end=&quot;1540&quot; data-start=&quot;1516&quot; data-ke-size=&quot;size26&quot;&gt;AI가 있으니까 더 빨리 갈 수는 있다&lt;/h2&gt;
&lt;p data-end=&quot;1567&quot; data-start=&quot;1542&quot; data-ke-size=&quot;size16&quot;&gt;요즘 개발하면서 AI를 정말 많이 쓰고 있다.&lt;/p&gt;
&lt;p data-end=&quot;1636&quot; data-start=&quot;1569&quot; data-ke-size=&quot;size16&quot;&gt;막히는 명령어를 물어볼 수도 있고&lt;br /&gt;오류 메시지를 그대로 보여줄 수도 있고&lt;br /&gt;배포 설정 파일도 같이 확인할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1646&quot; data-start=&quot;1638&quot; data-ke-size=&quot;size16&quot;&gt;확실히 편하다.&lt;/p&gt;
&lt;p data-end=&quot;1703&quot; data-start=&quot;1648&quot; data-ke-size=&quot;size16&quot;&gt;아마 예전이었다면 검색 결과 여러 개를 열어놓고 한참 헤맸을 일도 지금은 훨씬 빨리 해결하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;1726&quot; data-start=&quot;1705&quot; data-ke-size=&quot;size16&quot;&gt;그런데 배포를 시작하면서 다시 느꼈다.&lt;/p&gt;
&lt;p data-end=&quot;1779&quot; data-start=&quot;1728&quot; data-ke-size=&quot;size16&quot;&gt;AI가 명령어를 알려주는 것과&lt;br /&gt;내가 지금 무엇을 하고 있는지 이해하는 것은 다른 문제다.&lt;/p&gt;
&lt;p data-end=&quot;1805&quot; data-start=&quot;1781&quot; data-ke-size=&quot;size16&quot;&gt;명령어를 복사해서 배포에 성공할 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;1873&quot; data-start=&quot;1807&quot; data-ke-size=&quot;size16&quot;&gt;하지만 다음 프로젝트에서도 똑같은 문제가 생겼을 때 또 처음부터 물어봐야 한다면, 그건 내가 배운 게 아닐 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;1914&quot; data-start=&quot;1875&quot; data-ke-size=&quot;size16&quot;&gt;그래서 조금 느려지더라도 이번에는 가능한 한 이해하면서 가보기로 했다.&lt;/p&gt;
&lt;h2 data-end=&quot;1934&quot; data-start=&quot;1916&quot; data-ke-size=&quot;size26&quot;&gt;그리고 새벽 1시 반이 됐다&lt;/h2&gt;
&lt;p data-end=&quot;1951&quot; data-start=&quot;1936&quot; data-ke-size=&quot;size16&quot;&gt;문제는 시간이었던 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;1988&quot; data-start=&quot;1953&quot; data-ke-size=&quot;size16&quot;&gt;배포를 시작하고 이것저것 보다 보니 어느새 새벽 1시가 넘었다.&lt;/p&gt;
&lt;p data-end=&quot;2039&quot; data-start=&quot;1990&quot; data-ke-size=&quot;size16&quot;&gt;Ubuntu도 설치했고&lt;br /&gt;프로젝트도 확인했고&lt;br /&gt;배포를 위한 파일들도 만들기 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;2085&quot; data-start=&quot;2041&quot; data-ke-size=&quot;size16&quot;&gt;Git에서 변경된 파일을 확인해보니 실제로 설정 파일 두 개가 추가되어 있었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;.dockerignore
railway.toml&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2160&quot; data-start=&quot;2127&quot; data-ke-size=&quot;size16&quot;&gt;딱 여기까지 왔을 때 시간을 보니 거의 새벽 1시 반이었다.&lt;/p&gt;
&lt;p data-end=&quot;2196&quot; data-start=&quot;2162&quot; data-ke-size=&quot;size16&quot;&gt;조금만 더 하면 될 것 같은 느낌이 들면 계속 하고 싶어진다.&lt;/p&gt;
&lt;p data-end=&quot;2239&quot; data-start=&quot;2198&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이 상태에서 뭔가 잘못 건드리면 다음 날 내가 다시 수습해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;2249&quot; data-start=&quot;2241&quot; data-ke-size=&quot;size16&quot;&gt;그래서 멈췄다.&lt;/p&gt;
&lt;p data-end=&quot;2293&quot; data-start=&quot;2251&quot; data-ke-size=&quot;size16&quot;&gt;예전 같으면 프로그램이 내 컴퓨터에서 실행되는 것만으로도 만족했을 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;2310&quot; data-start=&quot;2295&quot; data-ke-size=&quot;size16&quot;&gt;지금은 조금 욕심이 생겼다.&lt;/p&gt;
&lt;p data-end=&quot;2351&quot; data-start=&quot;2312&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 만든 걸 다른 사람도 실제로 사용할 수 있게 만들고 싶다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2376&quot; data-start=&quot;2353&quot; data-ke-size=&quot;size16&quot;&gt;그렇게 하려니까 또 모르는 영역이 나왔다.&lt;/p&gt;
&lt;p data-end=&quot;2395&quot; data-start=&quot;2378&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 Linux와 서버였다.&lt;/p&gt;
&lt;p data-end=&quot;2429&quot; data-start=&quot;2397&quot; data-ke-size=&quot;size16&quot;&gt;개발은 정말 하나를 알면 다음 모르는 게 나오는 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;2444&quot; data-start=&quot;2431&quot; data-ke-size=&quot;size16&quot;&gt;그래도 예전과 다른 건,&lt;/p&gt;
&lt;p data-end=&quot;2469&quot; data-start=&quot;2446&quot; data-ke-size=&quot;size16&quot;&gt;이제는 그게 그렇게 싫지만은 않다는 거다.&lt;/p&gt;
&lt;p data-end=&quot;2489&quot; data-start=&quot;2471&quot; data-ke-size=&quot;size16&quot;&gt;오늘은 다시 Ubuntu를 켠다.&lt;/p&gt;
&lt;p data-end=&quot;2502&quot; data-start=&quot;2491&quot; data-ke-size=&quot;size16&quot;&gt;그리고 이번에는 정말&lt;/p&gt;
&lt;p data-end=&quot;2531&quot; data-start=&quot;2504&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;localhost 밖으로 나가보려고 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2561&quot; data-start=&quot;2533&quot; data-ke-size=&quot;size16&quot;&gt;다음 편에서는 실제로 프로젝트를 배포해보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/16</guid>
      <comments>https://nocklock.tistory.com/16#entry16comment</comments>
      <pubDate>Mon, 21 Sep 2026 08:23:07 +0900</pubDate>
    </item>
    <item>
      <title>Nocklock 개인정보처리방침</title>
      <link>https://nocklock.tistory.com/pages/Nocklock-%EA%B0%9C%EC%9D%B8%EC%A0%95%EB%B3%B4%EC%B2%98%EB%A6%AC%EB%B0%A9%EC%B9%A8</link>
      <description>&lt;p data-end=&quot;493&quot; data-start=&quot;458&quot; data-ke-size=&quot;size16&quot;&gt;Nocklock은 방문자의 개인정보 보호를 중요하게 생각합니다.&lt;/p&gt;
&lt;p data-end=&quot;575&quot; data-start=&quot;495&quot; data-ke-size=&quot;size16&quot;&gt;본 개인정보처리방침은 Nocklock 블로그 이용 과정에서 처리될 수 있는 정보와 외부 서비스 이용에 관한 내용을 안내하기 위해 작성되었습니다.&lt;/p&gt;
&lt;p data-end=&quot;598&quot; data-start=&quot;577&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;시행일: 2026년 9월 20일&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-end=&quot;618&quot; data-start=&quot;600&quot; data-ke-size=&quot;size23&quot;&gt;1. 수집될 수 있는 정보&lt;/h3&gt;
&lt;p data-end=&quot;671&quot; data-start=&quot;620&quot; data-ke-size=&quot;size16&quot;&gt;Nocklock은 방문자의 이름, 연락처 등의 개인정보를 별도로 요구하여 수집하지 않습니다.&lt;/p&gt;
&lt;p data-end=&quot;744&quot; data-start=&quot;673&quot; data-ke-size=&quot;size16&quot;&gt;다만 블로그 이용 과정에서 서비스 제공업체 또는 외부 서비스에 의해 다음과 같은 정보가 자동으로 생성되거나 처리될 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;823&quot; data-start=&quot;746&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;753&quot; data-start=&quot;746&quot;&gt;IP 주소&lt;/li&gt;
&lt;li data-end=&quot;763&quot; data-start=&quot;754&quot;&gt;브라우저 종류&lt;/li&gt;
&lt;li data-end=&quot;770&quot; data-start=&quot;764&quot;&gt;운영체제&lt;/li&gt;
&lt;li data-end=&quot;778&quot; data-start=&quot;771&quot;&gt;방문 일시&lt;/li&gt;
&lt;li data-end=&quot;787&quot; data-start=&quot;779&quot;&gt;방문 페이지&lt;/li&gt;
&lt;li data-end=&quot;800&quot; data-start=&quot;788&quot;&gt;쿠키(Cookie)&lt;/li&gt;
&lt;li data-end=&quot;811&quot; data-start=&quot;801&quot;&gt;기기 관련 정보&lt;/li&gt;
&lt;li data-end=&quot;823&quot; data-start=&quot;812&quot;&gt;서비스 이용 기록&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;878&quot; data-start=&quot;825&quot; data-ke-size=&quot;size16&quot;&gt;이러한 정보는 사이트 운영, 통계 분석, 보안 및 광고 제공 등의 목적으로 사용될 수 있습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;894&quot; data-start=&quot;880&quot; data-ke-size=&quot;size23&quot;&gt;2. 티스토리 이용&lt;/h3&gt;
&lt;p data-end=&quot;942&quot; data-start=&quot;896&quot; data-ke-size=&quot;size16&quot;&gt;Nocklock은 Kakao가 제공하는 Tistory 플랫폼을 이용하여 운영됩니다.&lt;/p&gt;
&lt;p data-end=&quot;1028&quot; data-start=&quot;944&quot; data-ke-size=&quot;size16&quot;&gt;티스토리 서비스 이용 과정에서 처리되는 개인정보 및 쿠키 등에 관한 사항은 Kakao 및 Tistory의 개인정보처리방침과 정책이 적용될 수 있습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1051&quot; data-start=&quot;1030&quot; data-ke-size=&quot;size23&quot;&gt;3. Google AdSense&lt;/h3&gt;
&lt;p data-end=&quot;1099&quot; data-start=&quot;1053&quot; data-ke-size=&quot;size16&quot;&gt;Nocklock은 Google AdSense를 이용하거나 향후 이용할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1176&quot; data-start=&quot;1101&quot; data-ke-size=&quot;size16&quot;&gt;Google을 포함한 제3자 광고 사업자는 쿠키를 사용하여 사용자의 이전 웹사이트 방문 기록 등을 기반으로 광고를 제공할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1246&quot; data-start=&quot;1178&quot; data-ke-size=&quot;size16&quot;&gt;Google 및 그 파트너는 사용자의 Nocklock 또는 다른 웹사이트 방문 기록을 기반으로 광고를 제공할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1300&quot; data-start=&quot;1248&quot; data-ke-size=&quot;size16&quot;&gt;사용자는 Google의 광고 설정 등을 통해 맞춤 광고 사용을 관리하거나 제한할 수 있습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1319&quot; data-start=&quot;1302&quot; data-ke-size=&quot;size23&quot;&gt;4. 쿠키(Cookie)&lt;/h3&gt;
&lt;p data-end=&quot;1360&quot; data-start=&quot;1321&quot; data-ke-size=&quot;size16&quot;&gt;쿠키는 웹사이트가 방문자의 브라우저에 저장하는 작은 데이터 파일입니다.&lt;/p&gt;
&lt;p data-end=&quot;1408&quot; data-start=&quot;1362&quot; data-ke-size=&quot;size16&quot;&gt;Nocklock 및 외부 서비스는 다음과 같은 목적으로 쿠키를 사용할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1471&quot; data-start=&quot;1410&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1421&quot; data-start=&quot;1410&quot;&gt;사이트 이용 분석&lt;/li&gt;
&lt;li data-end=&quot;1433&quot; data-start=&quot;1422&quot;&gt;사용자 환경 개선&lt;/li&gt;
&lt;li data-end=&quot;1441&quot; data-start=&quot;1434&quot;&gt;광고 제공&lt;/li&gt;
&lt;li data-end=&quot;1452&quot; data-start=&quot;1442&quot;&gt;광고 성과 측정&lt;/li&gt;
&lt;li data-end=&quot;1471&quot; data-start=&quot;1453&quot;&gt;부정 이용 및 보안 문제 탐지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1521&quot; data-start=&quot;1473&quot; data-ke-size=&quot;size16&quot;&gt;사용자는 브라우저 설정을 통해 쿠키 저장을 거부하거나 기존 쿠키를 삭제할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1571&quot; data-start=&quot;1523&quot; data-ke-size=&quot;size16&quot;&gt;쿠키 사용을 제한하는 경우 일부 웹사이트 기능이 정상적으로 동작하지 않을 수 있습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1585&quot; data-start=&quot;1573&quot; data-ke-size=&quot;size23&quot;&gt;5. 외부 링크&lt;/h3&gt;
&lt;p data-end=&quot;1653&quot; data-start=&quot;1587&quot; data-ke-size=&quot;size16&quot;&gt;Nocklock 게시물에는 GitHub, 공식 기술 문서 및 기타 외부 웹사이트로 연결되는 링크가 포함될 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1705&quot; data-start=&quot;1655&quot; data-ke-size=&quot;size16&quot;&gt;외부 웹사이트에서 이루어지는 개인정보 처리에는 해당 서비스의 개인정보처리방침이 적용됩니다.&lt;/p&gt;
&lt;p data-end=&quot;1751&quot; data-start=&quot;1707&quot; data-ke-size=&quot;size16&quot;&gt;Nocklock은 외부 웹사이트의 개인정보 처리 방식에 대해 책임지지 않습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1770&quot; data-start=&quot;1753&quot; data-ke-size=&quot;size23&quot;&gt;6. 광고 및 제휴 링크&lt;/h3&gt;
&lt;p data-end=&quot;1805&quot; data-start=&quot;1772&quot; data-ke-size=&quot;size16&quot;&gt;일부 게시물에는 광고 또는 제휴 링크가 포함될 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1868&quot; data-start=&quot;1807&quot; data-ke-size=&quot;size16&quot;&gt;사용자가 해당 링크를 통해 제품이나 서비스를 구매할 경우 Nocklock이 일정한 수수료를 받을 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1913&quot; data-start=&quot;1870&quot; data-ke-size=&quot;size16&quot;&gt;광고 또는 제휴 관계가 포함된 경우 가능한 범위에서 이를 명확하게 표시합니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1929&quot; data-start=&quot;1915&quot; data-ke-size=&quot;size23&quot;&gt;7. 댓글 및 문의&lt;/h3&gt;
&lt;p data-end=&quot;1981&quot; data-start=&quot;1931&quot; data-ke-size=&quot;size16&quot;&gt;방문자가 댓글이나 문의를 남기는 과정에서 직접 입력한 정보가 서비스에 저장될 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;2021&quot; data-start=&quot;1983&quot; data-ke-size=&quot;size16&quot;&gt;개인정보가 포함된 내용은 공개 댓글에 작성하지 않는 것을 권장합니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2041&quot; data-start=&quot;2023&quot; data-ke-size=&quot;size23&quot;&gt;8. 개인정보처리방침 변경&lt;/h3&gt;
&lt;p data-end=&quot;2101&quot; data-start=&quot;2043&quot; data-ke-size=&quot;size16&quot;&gt;본 개인정보처리방침은 관련 법령, 플랫폼 정책 또는 서비스 운영 방식의 변경에 따라 수정될 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;2128&quot; data-start=&quot;2103&quot; data-ke-size=&quot;size16&quot;&gt;변경되는 경우 본 페이지의 내용을 갱신합니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2139&quot; data-start=&quot;2130&quot; data-ke-size=&quot;size23&quot;&gt;9. 문의&lt;/h3&gt;
&lt;p data-end=&quot;2171&quot; data-start=&quot;2141&quot; data-ke-size=&quot;size16&quot;&gt;Nocklock 운영 및 개인정보처리방침에 관한 문의:&lt;/p&gt;
&lt;p data-end=&quot;2204&quot; data-start=&quot;2173&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Email: &lt;a data-end=&quot;2202&quot; data-start=&quot;2182&quot;&gt;henocklock@gmail.com&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2204&quot; data-start=&quot;2173&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2232&quot; data-start=&quot;2211&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;시행일: 2026년 9월 20일&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2246&quot; data-start=&quot;2234&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Nocklock&lt;/b&gt;&lt;/p&gt;</description>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/pages/Nocklock-%EA%B0%9C%EC%9D%B8%EC%A0%95%EB%B3%B4%EC%B2%98%EB%A6%AC%EB%B0%A9%EC%B9%A8</guid>
      <pubDate>Sun, 20 Sep 2026 17:56:56 +0900</pubDate>
    </item>
    <item>
      <title>About Nocklock &amp;mdash; 개발하고, 만들고, 검증합니다</title>
      <link>https://nocklock.tistory.com/pages/About-Nocklock-%E2%80%94-%EA%B0%9C%EB%B0%9C%ED%95%98%EA%B3%A0-%EB%A7%8C%EB%93%A4%EA%B3%A0-%EA%B2%80%EC%A6%9D%ED%95%A9%EB%8B%88%EB%8B%A4</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;logoAs.png&quot; data-origin-width=&quot;1731&quot; data-origin-height=&quot;909&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eCOkRx/dJMcaatnApB/AL4k9kaHh4vkH9gMESieIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eCOkRx/dJMcaatnApB/AL4k9kaHh4vkH9gMESieIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eCOkRx/dJMcaatnApB/AL4k9kaHh4vkH9gMESieIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeCOkRx%2FdJMcaatnApB%2FAL4k9kaHh4vkH9gMESieIk%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;1731&quot; height=&quot;909&quot; data-filename=&quot;logoAs.png&quot; data-origin-width=&quot;1731&quot; data-origin-height=&quot;909&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;240&quot; data-start=&quot;217&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요. &lt;b&gt;Nocklock&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;317&quot; data-start=&quot;242&quot; data-ke-size=&quot;size16&quot;&gt;자바 기반의 웹 개발을 해왔고, 지금은 다시 개발자로서 기본기를 다지는 동시에 직접 서비스를 만들고 배포하는 과정을 기록하고 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;349&quot; data-start=&quot;319&quot; data-ke-size=&quot;size16&quot;&gt;이 블로그는 단순히 기술 문서를 정리하는 곳이라기보다,&lt;/p&gt;
&lt;p data-end=&quot;401&quot; data-start=&quot;351&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;직접 만들고, 실패하고, 고치면서 알게 된 것들을 남기는 개발 기록&lt;/b&gt;에 가깝습니다.&lt;/p&gt;
&lt;hr data-end=&quot;406&quot; data-start=&quot;403&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;418&quot; data-start=&quot;408&quot; data-ke-size=&quot;size26&quot;&gt;무엇을 해왔나&lt;/h2&gt;
&lt;p data-end=&quot;459&quot; data-start=&quot;420&quot; data-ke-size=&quot;size16&quot;&gt;Java 기반 웹 서비스를 개발하며 다음과 같은 기술을 사용해왔습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;605&quot; data-start=&quot;461&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;467&quot; data-start=&quot;461&quot;&gt;Java&lt;/li&gt;
&lt;li data-end=&quot;494&quot; data-start=&quot;468&quot;&gt;Spring MVC / Spring Boot&lt;/li&gt;
&lt;li data-end=&quot;516&quot; data-start=&quot;495&quot;&gt;JSP / JSTL / jQuery&lt;/li&gt;
&lt;li data-end=&quot;527&quot; data-start=&quot;517&quot;&gt;REST API&lt;/li&gt;
&lt;li data-end=&quot;548&quot; data-start=&quot;528&quot;&gt;PostgreSQL / MySQL&lt;/li&gt;
&lt;li data-end=&quot;563&quot; data-start=&quot;549&quot;&gt;Git / Gradle&lt;/li&gt;
&lt;li data-end=&quot;577&quot; data-start=&quot;564&quot;&gt;Linux / WSL&lt;/li&gt;
&lt;li data-end=&quot;586&quot; data-start=&quot;578&quot;&gt;Docker&lt;/li&gt;
&lt;li data-end=&quot;605&quot; data-start=&quot;587&quot;&gt;Cloud Deployment&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;661&quot; data-start=&quot;607&quot; data-ke-size=&quot;size16&quot;&gt;실제 웹 서비스와 CRM 개발을 경험했고, 보안 대응이나 데이터 처리와 관련된 작업도 해왔습니다.&lt;/p&gt;
&lt;p data-end=&quot;696&quot; data-start=&quot;663&quot; data-ke-size=&quot;size16&quot;&gt;최근에는 개발 과정에서 AI를 적극적으로 사용하고 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;728&quot; data-start=&quot;698&quot; data-ke-size=&quot;size16&quot;&gt;하지만 AI가 만들어준 결과를 그대로 사용하는 것보다,&lt;/p&gt;
&lt;p data-end=&quot;783&quot; data-start=&quot;730&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;빌드하고, 테스트하고, 실제로 동작하는지 직접 확인하는 과정&lt;/b&gt;을 더 중요하게 생각합니다.&lt;/p&gt;
&lt;hr data-end=&quot;788&quot; data-start=&quot;785&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;804&quot; data-start=&quot;790&quot; data-ke-size=&quot;size26&quot;&gt;지금 만들고 있는 것&lt;/h2&gt;
&lt;p data-end=&quot;852&quot; data-start=&quot;806&quot; data-ke-size=&quot;size16&quot;&gt;최근에는 &lt;b&gt;Security Lens&lt;/b&gt;라는 프로젝트를 직접 기획하고 개발했습니다.&lt;/p&gt;
&lt;p data-end=&quot;902&quot; data-start=&quot;854&quot; data-ke-size=&quot;size16&quot;&gt;이미지 안에 포함된 개인정보와 메타데이터를 분석하고 위험 요소를 보여주는 서비스입니다.&lt;/p&gt;
&lt;p data-end=&quot;929&quot; data-start=&quot;904&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트를 만들면서 경험한 내용을 바탕으로&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1027&quot; data-start=&quot;931&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;939&quot; data-start=&quot;931&quot;&gt;API 설계&lt;/li&gt;
&lt;li data-end=&quot;945&quot; data-start=&quot;940&quot;&gt;OCR&lt;/li&gt;
&lt;li data-end=&quot;955&quot; data-start=&quot;946&quot;&gt;개인정보 탐지&lt;/li&gt;
&lt;li data-end=&quot;965&quot; data-start=&quot;956&quot;&gt;EXIF 분석&lt;/li&gt;
&lt;li data-end=&quot;976&quot; data-start=&quot;966&quot;&gt;프론트엔드 연결&lt;/li&gt;
&lt;li data-end=&quot;988&quot; data-start=&quot;977&quot;&gt;Git / WSL&lt;/li&gt;
&lt;li data-end=&quot;997&quot; data-start=&quot;989&quot;&gt;Docker&lt;/li&gt;
&lt;li data-end=&quot;1014&quot; data-start=&quot;998&quot;&gt;Spring Boot 배포&lt;/li&gt;
&lt;li data-end=&quot;1027&quot; data-start=&quot;1015&quot;&gt;AI를 활용한 개발&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1051&quot; data-start=&quot;1029&quot; data-ke-size=&quot;size16&quot;&gt;같은 내용을 블로그에 기록하고 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1071&quot; data-start=&quot;1053&quot; data-ke-size=&quot;size16&quot;&gt;성공한 과정만 정리하지 않습니다.&lt;/p&gt;
&lt;p data-end=&quot;1127&quot; data-start=&quot;1073&quot; data-ke-size=&quot;size16&quot;&gt;실제로 막혔던 부분과 잘못 판단했던 부분, 다시 수정한 과정까지 가능한 한 같이 남기려고 합니다.&lt;/p&gt;
&lt;hr data-end=&quot;1132&quot; data-start=&quot;1129&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1153&quot; data-start=&quot;1134&quot; data-ke-size=&quot;size26&quot;&gt;Nocklock에서 다루는 것&lt;/h2&gt;
&lt;h3 data-end=&quot;1165&quot; data-start=&quot;1155&quot; data-ke-size=&quot;size23&quot;&gt;RE:개발자&lt;/h3&gt;
&lt;p data-end=&quot;1193&quot; data-start=&quot;1167&quot; data-ke-size=&quot;size16&quot;&gt;다시 자바 개발자로 성장하는 과정을 기록합니다.&lt;/p&gt;
&lt;p data-end=&quot;1253&quot; data-start=&quot;1195&quot; data-ke-size=&quot;size16&quot;&gt;기본적인 개발 환경부터 Spring Boot, API, 테스트, 배포까지 직접 다시 만들어가고 있습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1264&quot; data-start=&quot;1255&quot; data-ke-size=&quot;size23&quot;&gt;개발 노트&lt;/h3&gt;
&lt;p data-end=&quot;1288&quot; data-start=&quot;1266&quot; data-ke-size=&quot;size16&quot;&gt;개발하면서 실제로 만난 문제를 다룹니다.&lt;/p&gt;
&lt;p data-end=&quot;1304&quot; data-start=&quot;1290&quot; data-ke-size=&quot;size16&quot;&gt;검색해서 정리한 정보보다는&lt;/p&gt;
&lt;p data-end=&quot;1346&quot; data-start=&quot;1306&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;내 프로젝트에서 실제로 어떤 문제가 발생했고 어떻게 해결했는가&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1359&quot; data-start=&quot;1348&quot; data-ke-size=&quot;size16&quot;&gt;에 초점을 맞춥니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1375&quot; data-start=&quot;1361&quot; data-ke-size=&quot;size23&quot;&gt;기술이 조금 무섭다&lt;/h3&gt;
&lt;p data-end=&quot;1428&quot; data-start=&quot;1377&quot; data-ke-size=&quot;size16&quot;&gt;개인정보, 플랫폼, AI처럼 편리하지만 한편으로는 생각해볼 부분이 있는 기술을 이야기합니다.&lt;/p&gt;
&lt;p data-end=&quot;1446&quot; data-start=&quot;1430&quot; data-ke-size=&quot;size16&quot;&gt;기술 자체를 두려워하기보다는,&lt;/p&gt;
&lt;p data-end=&quot;1491&quot; data-start=&quot;1448&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;우리가 사용하는 기술을 조금 더 알고 사용하자&lt;/b&gt;는 생각에서 시작했습니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1505&quot; data-start=&quot;1493&quot; data-ke-size=&quot;size23&quot;&gt;AI TOOLS&lt;/h3&gt;
&lt;p data-end=&quot;1560&quot; data-start=&quot;1507&quot; data-ke-size=&quot;size16&quot;&gt;ChatGPT, Claude 등 AI 도구를 실제 개발과 일상에서 어떻게 사용하는지 기록합니다.&lt;/p&gt;
&lt;p data-end=&quot;1615&quot; data-start=&quot;1562&quot; data-ke-size=&quot;size16&quot;&gt;코드 생성뿐 아니라 문서 분석, 조사, 문제 해결, 콘텐츠 제작 등 실제 사용 경험을 다룹니다.&lt;/p&gt;
&lt;h3 data-end=&quot;1628&quot; data-start=&quot;1617&quot; data-ke-size=&quot;size23&quot;&gt;English&lt;/h3&gt;
&lt;p data-end=&quot;1680&quot; data-start=&quot;1630&quot; data-ke-size=&quot;size16&quot;&gt;직접 겪은 개발 문제 중 영어권 개발자에게도 도움이 될 수 있는 내용을 영어로 정리합니다.&lt;/p&gt;
&lt;hr data-end=&quot;1685&quot; data-start=&quot;1682&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1697&quot; data-start=&quot;1687&quot; data-ke-size=&quot;size26&quot;&gt;왜 기록하는가&lt;/h2&gt;
&lt;p data-end=&quot;1722&quot; data-start=&quot;1699&quot; data-ke-size=&quot;size16&quot;&gt;개발을 다시 시작하면서 하나를 느꼈습니다.&lt;/p&gt;
&lt;p data-end=&quot;1753&quot; data-start=&quot;1724&quot; data-ke-size=&quot;size16&quot;&gt;알고 있다고 생각했던 것도 직접 만들어보면 다릅니다.&lt;/p&gt;
&lt;p data-end=&quot;1790&quot; data-start=&quot;1755&quot; data-ke-size=&quot;size16&quot;&gt;로컬에서는 잘 돌아가던 애플리케이션이 배포하면 실패하기도 하고,&lt;/p&gt;
&lt;p data-end=&quot;1829&quot; data-start=&quot;1792&quot; data-ke-size=&quot;size16&quot;&gt;Git 설정 하나 때문에 모든 파일이 변경된 것처럼 나오기도 하고,&lt;/p&gt;
&lt;p data-end=&quot;1873&quot; data-start=&quot;1831&quot; data-ke-size=&quot;size16&quot;&gt;AI가 만들어준 코드는 그럴듯하지만 실제로 실행하면 문제가 생기기도 합니다.&lt;/p&gt;
&lt;p data-end=&quot;1925&quot; data-start=&quot;1875&quot; data-ke-size=&quot;size16&quot;&gt;그래서 Nocklock에서는 결과보다 &lt;b&gt;그 결과에 도달하는 과정&lt;/b&gt;을 기록하려고 합니다.&lt;/p&gt;
&lt;p data-end=&quot;1942&quot; data-start=&quot;1927&quot; data-ke-size=&quot;size16&quot;&gt;그리고 그 기록들이 쌓이면,&lt;/p&gt;
&lt;p data-end=&quot;1981&quot; data-start=&quot;1944&quot; data-ke-size=&quot;size16&quot;&gt;다음 프로젝트에서는 같은 실수를 조금 덜 할 수 있다고 생각합니다.&lt;/p&gt;
&lt;hr data-end=&quot;1986&quot; data-start=&quot;1983&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2001&quot; data-start=&quot;1988&quot; data-ke-size=&quot;size26&quot;&gt;AI 사용에 대하여&lt;/h2&gt;
&lt;p data-end=&quot;2036&quot; data-start=&quot;2003&quot; data-ke-size=&quot;size16&quot;&gt;Nocklock의 개발과 콘텐츠 제작에는 AI가 사용됩니다.&lt;/p&gt;
&lt;p data-end=&quot;2090&quot; data-start=&quot;2038&quot; data-ke-size=&quot;size16&quot;&gt;아이디어 정리, 코드 리뷰, 자료 조사, 글의 구조를 만드는 데 AI의 도움을 받기도 합니다.&lt;/p&gt;
&lt;p data-end=&quot;2125&quot; data-start=&quot;2092&quot; data-ke-size=&quot;size16&quot;&gt;다만 AI가 작성한 결과를 그대로 사실로 취급하지 않습니다.&lt;/p&gt;
&lt;p data-end=&quot;2141&quot; data-start=&quot;2127&quot; data-ke-size=&quot;size16&quot;&gt;기술적인 내용은 가능한 한&lt;/p&gt;
&lt;p data-end=&quot;2171&quot; data-start=&quot;2143&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;직접 실행 &amp;rarr; 공식 문서 확인 &amp;rarr; 결과 검증&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2182&quot; data-start=&quot;2173&quot; data-ke-size=&quot;size16&quot;&gt;과정을 거칩니다.&lt;/p&gt;
&lt;p data-end=&quot;2205&quot; data-start=&quot;2184&quot; data-ke-size=&quot;size16&quot;&gt;AI는 개발자를 대신하는 도구라기보다,&lt;/p&gt;
&lt;p data-end=&quot;2244&quot; data-start=&quot;2207&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;더 빠르게 가설을 만들고 검증하기 위한 도구&lt;/b&gt;라고 생각합니다.&lt;/p&gt;
&lt;hr data-end=&quot;2249&quot; data-start=&quot;2246&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2262&quot; data-start=&quot;2251&quot; data-ke-size=&quot;size26&quot;&gt;Nocklock&lt;/h2&gt;
&lt;p data-end=&quot;2290&quot; data-start=&quot;2264&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Develop. Verify. Ship.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2332&quot; data-start=&quot;2292&quot; data-ke-size=&quot;size16&quot;&gt;직접 만들고, 직접 확인하고, 실제로 세상에 내보내는 과정을 기록합니다.&lt;/p&gt;
&lt;p data-end=&quot;924&quot; data-start=&quot;868&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Contact&lt;/b&gt;&lt;br /&gt;Nocklock 관련 문의: &lt;b&gt;&lt;a data-end=&quot;922&quot; data-start=&quot;902&quot;&gt;henocklock@gmail.com&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;968&quot; data-start=&quot;929&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/pages/About-Nocklock-%E2%80%94-%EA%B0%9C%EB%B0%9C%ED%95%98%EA%B3%A0-%EB%A7%8C%EB%93%A4%EA%B3%A0-%EA%B2%80%EC%A6%9D%ED%95%A9%EB%8B%88%EB%8B%A4</guid>
      <pubDate>Sun, 20 Sep 2026 17:49:59 +0900</pubDate>
    </item>
    <item>
      <title>I Shipped a Real Spring Boot MVP &amp;mdash; Here&amp;rsquo;s What I Checked Before Calling It Done</title>
      <link>https://nocklock.tistory.com/26</link>
      <description>&lt;p data-end=&quot;266&quot; data-start=&quot;187&quot; data-ke-size=&quot;size18&quot;&gt;A few days ago, Security Lens was still mostly a project running on my machine.&lt;/p&gt;
&lt;p data-end=&quot;456&quot; data-start=&quot;268&quot; data-ke-size=&quot;size18&quot;&gt;The API worked. OCR worked. Sensitive information could be detected, and I could extract metadata from images and calculate a risk score. Technically, a lot of things were already working.&lt;/p&gt;
&lt;p data-end=&quot;499&quot; data-start=&quot;458&quot; data-ke-size=&quot;size18&quot;&gt;But I wasn&amp;rsquo;t comfortable calling it done.&lt;/p&gt;
&lt;p data-end=&quot;521&quot; data-start=&quot;501&quot; data-ke-size=&quot;size18&quot;&gt;Today, I finally am.&lt;/p&gt;
&lt;p data-end=&quot;774&quot; data-start=&quot;523&quot; data-ke-size=&quot;size18&quot;&gt;Security Lens can take an image, analyze the information inside it, detect potentially sensitive data, remove or mask what the user chooses, generate a protected image, and return something that can actually be used outside my development environment.&lt;/p&gt;
&lt;p data-end=&quot;985&quot; data-start=&quot;776&quot; data-ke-size=&quot;size18&quot;&gt;The interesting part is that the last few days weren&amp;rsquo;t really about adding impressive features. They were mostly about finding all the small reasons why a working project wasn&amp;rsquo;t yet something I wanted to ship.&lt;/p&gt;
&lt;p data-end=&quot;1025&quot; data-start=&quot;987&quot; data-ke-size=&quot;size18&quot;&gt;That changed how I think about an MVP.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오후 05_23_17.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ub4ZW/dJMcaiLzad1/FnsQY5rX6hf6H6fC0T2ejK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ub4ZW/dJMcaiLzad1/FnsQY5rX6hf6H6fC0T2ejK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ub4ZW/dJMcaiLzad1/FnsQY5rX6hf6H6fC0T2ejK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fub4ZW%2FdJMcaiLzad1%2FFnsQY5rX6hf6H6fC0T2ejK%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; alt=&quot;Spring Boot MVP&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오후 05_23_17.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-end=&quot;1030&quot; data-start=&quot;1027&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1088&quot; data-start=&quot;1032&quot; data-section-id=&quot;10817rm&quot; data-ke-size=&quot;size26&quot;&gt;A working feature isn&amp;rsquo;t the same as a working product&lt;/h2&gt;
&lt;p data-end=&quot;1193&quot; data-start=&quot;1090&quot; data-ke-size=&quot;size18&quot;&gt;Security Lens started with a fairly simple idea: images often contain more information than we realize.&lt;/p&gt;
&lt;p data-end=&quot;1418&quot; data-start=&quot;1195&quot; data-ke-size=&quot;size18&quot;&gt;There is the information we can see&amp;mdash;names, phone numbers, email addresses, documents&amp;mdash;and there is also information hidden inside the file itself, such as EXIF metadata, GPS information, capture time, and device information.&lt;/p&gt;
&lt;p data-end=&quot;1615&quot; data-start=&quot;1420&quot; data-ke-size=&quot;size18&quot;&gt;So I built a Spring Boot application that analyzes uploaded images. Over time, it became able to process OCR text, detect personal information, inspect image metadata, and calculate a risk level.&lt;/p&gt;
&lt;p data-end=&quot;1695&quot; data-start=&quot;1617&quot; data-ke-size=&quot;size18&quot;&gt;At that point, I could send an image to the API and get a valid JSON response.&lt;/p&gt;
&lt;p data-end=&quot;1733&quot; data-start=&quot;1697&quot; data-ke-size=&quot;size18&quot;&gt;For a while, that felt like success.&lt;/p&gt;
&lt;p data-end=&quot;1841&quot; data-start=&quot;1735&quot; data-ke-size=&quot;size18&quot;&gt;Then I started testing the application as something another person would actually use. That was different.&lt;/p&gt;
&lt;p data-end=&quot;2078&quot; data-start=&quot;1843&quot; data-ke-size=&quot;size18&quot;&gt;A user doesn&amp;rsquo;t care that my controller returned 200 OK. They care whether they can upload an image, understand the result, protect the information they don&amp;rsquo;t want to share, get the processed image back, and use it normally afterward.&lt;/p&gt;
&lt;p data-end=&quot;2133&quot; data-start=&quot;2080&quot; data-ke-size=&quot;size18&quot;&gt;That full flow became my new definition of &amp;ldquo;working.&amp;rdquo;&lt;/p&gt;
&lt;hr data-end=&quot;2138&quot; data-start=&quot;2135&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2197&quot; data-start=&quot;2140&quot; data-section-id=&quot;142p8wq&quot; data-ke-size=&quot;size26&quot;&gt;Deployment exposed things local development had hidden&lt;/h2&gt;
&lt;p data-end=&quot;2260&quot; data-start=&quot;2199&quot; data-ke-size=&quot;size18&quot;&gt;The first big change happened when I moved toward deployment.&lt;/p&gt;
&lt;p data-end=&quot;2420&quot; data-start=&quot;2262&quot; data-ke-size=&quot;size18&quot;&gt;My Spring Boot application had been running locally on Windows. I knew the environment because I created it. A deployment environment didn&amp;rsquo;t know any of that.&lt;/p&gt;
&lt;p data-end=&quot;2559&quot; data-start=&quot;2422&quot; data-ke-size=&quot;size18&quot;&gt;Ports suddenly mattered differently.&lt;br /&gt;Environment variables mattered.&lt;br /&gt;Linux mattered.&lt;br /&gt;Docker mattered.&lt;br /&gt;Even line endings mattered.&lt;/p&gt;
&lt;p data-end=&quot;2707&quot; data-start=&quot;2561&quot; data-ke-size=&quot;size18&quot;&gt;I ran into the classic 8080 already in use problem locally, and later had to think about dynamically assigned ports in a deployment environment.&lt;/p&gt;
&lt;p data-end=&quot;2782&quot; data-start=&quot;2709&quot; data-ke-size=&quot;size18&quot;&gt;A configuration like this stopped looking like a random production trick:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;server.port=${PORT:8080}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2919&quot; data-start=&quot;2828&quot; data-ke-size=&quot;size18&quot;&gt;Locally, I can use 8080. In an environment like Railway, the platform can provide the port.&lt;/p&gt;
&lt;p data-end=&quot;3018&quot; data-start=&quot;2921&quot; data-ke-size=&quot;size18&quot;&gt;Simple&amp;mdash;but I only really understood why I needed it after I had to deploy the application myself.&lt;/p&gt;
&lt;p data-end=&quot;3183&quot; data-start=&quot;3020&quot; data-ke-size=&quot;size18&quot;&gt;I had the same experience with Docker, WSL, .dockerignore, and environment-specific configuration. Deployment kept exposing assumptions I didn&amp;rsquo;t know I had made.&lt;/p&gt;
&lt;p data-end=&quot;3212&quot; data-start=&quot;3185&quot; data-ke-size=&quot;size18&quot;&gt;I wrote more about that in:&lt;/p&gt;
&lt;p data-end=&quot;3286&quot; data-start=&quot;3214&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Spring Boot Works Locally But Fails After Deployment: What I Checked&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3445&quot; data-start=&quot;3288&quot; data-ke-size=&quot;size18&quot;&gt;That was probably the point where this project stopped feeling like &amp;ldquo;a Spring Boot project&amp;rdquo; and started feeling like something I was actually trying to ship.&lt;/p&gt;
&lt;hr data-end=&quot;3450&quot; data-start=&quot;3447&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3513&quot; data-start=&quot;3452&quot; data-section-id=&quot;1ya70f&quot; data-ke-size=&quot;size26&quot;&gt;AI helped a lot, but it also created a new kind of problem&lt;/h2&gt;
&lt;p data-end=&quot;3562&quot; data-start=&quot;3515&quot; data-ke-size=&quot;size18&quot;&gt;I used AI heavily while building Security Lens.&lt;/p&gt;
&lt;p data-end=&quot;3762&quot; data-start=&quot;3564&quot; data-ke-size=&quot;size18&quot;&gt;I don&amp;rsquo;t really try to hide that. It helped me write code faster, inspect unfamiliar configuration, debug problems, and move through parts of the stack that would otherwise have taken me much longer.&lt;/p&gt;
&lt;p data-end=&quot;3817&quot; data-start=&quot;3764&quot; data-ke-size=&quot;size18&quot;&gt;But there was one problem that changed how I used it.&lt;/p&gt;
&lt;p data-end=&quot;3915&quot; data-start=&quot;3819&quot; data-ke-size=&quot;size18&quot;&gt;OCR is imperfect. Let&amp;rsquo;s say OCR reads a name incorrectly. An LLM may look at the text and think:&lt;/p&gt;
&lt;p data-end=&quot;3983&quot; data-start=&quot;3919&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;That is probably a typo. I know what this was supposed to say.&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;4029&quot; data-start=&quot;3985&quot; data-ke-size=&quot;size18&quot;&gt;For a normal assistant, that can be helpful.&lt;/p&gt;
&lt;p data-end=&quot;4070&quot; data-start=&quot;4031&quot; data-ke-size=&quot;size18&quot;&gt;For Security Lens, it can be dangerous.&lt;/p&gt;
&lt;p data-end=&quot;4239&quot; data-start=&quot;4072&quot; data-ke-size=&quot;size18&quot;&gt;If the system is supposed to tell me what is actually inside an image, the AI should not quietly replace the source text with what it thinks the text should have been.&lt;/p&gt;
&lt;p data-end=&quot;4343&quot; data-start=&quot;4241&quot; data-ke-size=&quot;size18&quot;&gt;That meant I couldn&amp;rsquo;t just ask an LLM to &amp;ldquo;find personal information&amp;rdquo; and trust everything it returned.&lt;/p&gt;
&lt;p data-end=&quot;4365&quot; data-start=&quot;4345&quot; data-ke-size=&quot;size18&quot;&gt;I needed boundaries.&lt;/p&gt;
&lt;p data-end=&quot;4405&quot; data-start=&quot;4367&quot; data-ke-size=&quot;size18&quot;&gt;The system gradually became less like:&lt;/p&gt;
&lt;p data-end=&quot;4428&quot; data-start=&quot;4407&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;OCR &amp;rarr; AI &amp;rarr; Result&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4444&quot; data-start=&quot;4430&quot; data-ke-size=&quot;size18&quot;&gt;and more like:&lt;/p&gt;
&lt;p data-end=&quot;4511&quot; data-start=&quot;4446&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;OCR &amp;rarr; Deterministic Rules &amp;rarr; AI Analysis &amp;rarr; Validation &amp;rarr; Result&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;4634&quot; data-start=&quot;4513&quot; data-ke-size=&quot;size18&quot;&gt;The AI could help interpret the data, but it couldn&amp;rsquo;t be the final authority on what the source image actually contained.&lt;/p&gt;
&lt;p data-end=&quot;4668&quot; data-start=&quot;4636&quot; data-ke-size=&quot;size18&quot;&gt;That was a useful lesson for me.&lt;/p&gt;
&lt;p data-end=&quot;4784&quot; data-start=&quot;4670&quot; data-ke-size=&quot;size18&quot;&gt;AI-assisted development isn&amp;rsquo;t just about getting code from an AI faster. Sometimes the more important question is:&lt;/p&gt;
&lt;p data-end=&quot;4822&quot; data-start=&quot;4786&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Where should I stop trusting it?&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;4827&quot; data-start=&quot;4824&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;916&quot; data-start=&quot;871&quot; data-section-id=&quot;k66nqi&quot; data-ke-size=&quot;size26&quot;&gt;Functional testing didn&amp;rsquo;t catch everything&lt;/h2&gt;
&lt;p data-end=&quot;1026&quot; data-start=&quot;918&quot; data-ke-size=&quot;size18&quot;&gt;At one point, individual features were working well enough that I thought the application was close to done.&lt;/p&gt;
&lt;p data-end=&quot;1060&quot; data-start=&quot;1028&quot; data-ke-size=&quot;size18&quot;&gt;Then I ran load testing with k6.&lt;/p&gt;
&lt;p data-end=&quot;1130&quot; data-start=&quot;1062&quot; data-ke-size=&quot;size18&quot;&gt;That uncovered a problem normal feature testing hadn&amp;rsquo;t made obvious.&lt;/p&gt;
&lt;p data-end=&quot;1256&quot; data-start=&quot;1132&quot; data-ke-size=&quot;size18&quot;&gt;OCR is expensive. A single request looked fine, but multiple requests running OCR at the same time behaved very differently.&lt;/p&gt;
&lt;p data-end=&quot;1473&quot; data-start=&quot;1258&quot; data-ke-size=&quot;size18&quot;&gt;In one full-flow test with three virtual users, all FAST and DEEP requests completed successfully with a 0% HTTP failure rate. FAST had a p95 response time of about 6.4 seconds, while DEEP reached about 9.5 seconds.&lt;/p&gt;
&lt;p data-end=&quot;1533&quot; data-start=&quot;1475&quot; data-ke-size=&quot;size18&quot;&gt;So from the outside, the application still looked healthy.&lt;/p&gt;
&lt;p data-end=&quot;1633&quot; data-start=&quot;1535&quot; data-ke-size=&quot;size18&quot;&gt;But under concurrent external requests, the Railway logs eventually showed something more serious:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;java.lang.OutOfMemoryError: Java heap space&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1723&quot; data-start=&quot;1692&quot; data-ke-size=&quot;size18&quot;&gt;That changed the question from:&lt;/p&gt;
&lt;p data-end=&quot;1743&quot; data-start=&quot;1725&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Does OCR work?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1748&quot; data-start=&quot;1745&quot; data-ke-size=&quot;size18&quot;&gt;to:&lt;/p&gt;
&lt;p data-end=&quot;1831&quot; data-start=&quot;1750&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;How many OCR jobs should this application be allowed to run at the same time?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2001&quot; data-start=&quot;1833&quot; data-ke-size=&quot;size18&quot;&gt;I traced the expensive work back to the OCR execution path and decided to limit concurrent OCR jobs instead of allowing every incoming request to start one immediately.&lt;/p&gt;
&lt;p data-end=&quot;2047&quot; data-start=&quot;2003&quot; data-ke-size=&quot;size18&quot;&gt;The current implementation uses a semaphore:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;private final Semaphore semaphore = new Semaphore(2);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2317&quot; data-start=&quot;2116&quot; data-ke-size=&quot;size18&quot;&gt;The number 2 is not something I consider a universally optimal value. I chose it conservatively for this deployment environment because I wanted memory stability before trying to maximize throughput.&lt;/p&gt;
&lt;p data-end=&quot;2402&quot; data-start=&quot;2319&quot; data-ke-size=&quot;size18&quot;&gt;After adding the limit, I ran another FAST test with five concurrent virtual users.&lt;/p&gt;
&lt;p data-end=&quot;2548&quot; data-start=&quot;2404&quot; data-ke-size=&quot;size18&quot;&gt;All five requests completed with HTTP 200 responses and a 0% failure rate, and I did not see another OOM or application restart during that run.&lt;/p&gt;
&lt;p data-end=&quot;2576&quot; data-start=&quot;2550&quot; data-ke-size=&quot;size18&quot;&gt;But there was a trade-off.&lt;/p&gt;
&lt;p data-end=&quot;2683&quot; data-start=&quot;2578&quot; data-ke-size=&quot;size18&quot;&gt;The p95 response time increased to roughly 55 seconds because requests now had to wait for an OCR permit.&lt;/p&gt;
&lt;p data-end=&quot;2730&quot; data-start=&quot;2685&quot; data-ke-size=&quot;size18&quot;&gt;So the change didn&amp;rsquo;t magically make OCR fast.&lt;/p&gt;
&lt;p data-end=&quot;2759&quot; data-start=&quot;2732&quot; data-ke-size=&quot;size18&quot;&gt;It changed the system from:&lt;/p&gt;
&lt;p data-end=&quot;2810&quot; data-start=&quot;2761&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;ldquo;accept everything at once and risk crashing&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2815&quot; data-start=&quot;2812&quot; data-ke-size=&quot;size18&quot;&gt;to:&lt;/p&gt;
&lt;p data-end=&quot;2883&quot; data-start=&quot;2817&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;ldquo;control expensive work and finish requests more predictably.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2960&quot; data-start=&quot;2885&quot; data-ke-size=&quot;size18&quot;&gt;That was a much more useful result than simply saying the load test passed.&lt;/p&gt;
&lt;p data-end=&quot;3020&quot; data-start=&quot;2962&quot; data-ke-size=&quot;size18&quot;&gt;It also added another item to my mental release checklist:&lt;/p&gt;
&lt;p data-end=&quot;3104&quot; data-start=&quot;3022&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Test the behavior of the system, not just the correctness of a single request.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;5980&quot; data-start=&quot;5977&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;6037&quot; data-start=&quot;5982&quot; data-section-id=&quot;4tj670&quot; data-ke-size=&quot;size26&quot;&gt;I tested the whole flow outside my development setup&lt;/h2&gt;
&lt;p data-end=&quot;6100&quot; data-start=&quot;6039&quot; data-ke-size=&quot;size18&quot;&gt;This was probably the moment the MVP finally felt real to me.&lt;/p&gt;
&lt;p data-end=&quot;6215&quot; data-start=&quot;6102&quot; data-ke-size=&quot;size18&quot;&gt;I stopped testing individual functions and tried to use Security Lens the way I expected a normal user to use it.&lt;/p&gt;
&lt;p data-end=&quot;6408&quot; data-start=&quot;6217&quot; data-ke-size=&quot;size18&quot;&gt;Upload an actual image. Analyze it. Check what the system detects. Choose what should be protected. Generate the protected version. Download it. Move it to a phone. Share the result normally.&lt;/p&gt;
&lt;p data-end=&quot;6458&quot; data-start=&quot;6410&quot; data-ke-size=&quot;size18&quot;&gt;I even tested the final image through KakaoTalk.&lt;/p&gt;
&lt;p data-end=&quot;6570&quot; data-start=&quot;6460&quot; data-ke-size=&quot;size18&quot;&gt;That last step sounds almost trivial compared to OCR or AI integration, but it answered an important question:&lt;/p&gt;
&lt;p data-end=&quot;6651&quot; data-start=&quot;6572&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Did I build a demo, or did I build something that produces a usable result?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;6699&quot; data-start=&quot;6653&quot; data-ke-size=&quot;size18&quot;&gt;For this MVP, that was the test I cared about.&lt;/p&gt;
&lt;p data-end=&quot;6807&quot; data-start=&quot;6701&quot; data-ke-size=&quot;size18&quot;&gt;The application didn&amp;rsquo;t need every feature I could imagine. It needed to complete the job it claimed to do.&lt;/p&gt;
&lt;hr data-end=&quot;6812&quot; data-start=&quot;6809&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;6874&quot; data-start=&quot;6814&quot; data-section-id=&quot;1pzzrf7&quot; data-ke-size=&quot;size26&quot;&gt;The hardest final decision was not adding another feature&lt;/h2&gt;
&lt;p data-end=&quot;6913&quot; data-start=&quot;6876&quot; data-ke-size=&quot;size18&quot;&gt;There are still things I can improve.&lt;/p&gt;
&lt;p data-end=&quot;7098&quot; data-start=&quot;6915&quot; data-ke-size=&quot;size18&quot;&gt;Detection can cover more patterns. Bounding boxes can become more precise. Some edge cases can be handled better. The UI can improve. AI analysis can improve. Performance can improve.&lt;/p&gt;
&lt;p data-end=&quot;7137&quot; data-start=&quot;7100&quot; data-ke-size=&quot;size18&quot;&gt;And that list could continue forever.&lt;/p&gt;
&lt;p data-end=&quot;7216&quot; data-start=&quot;7139&quot; data-ke-size=&quot;size18&quot;&gt;For most of this project, whenever I found another weakness, my instinct was:&lt;/p&gt;
&lt;p data-end=&quot;7244&quot; data-start=&quot;7220&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;I should fix this too.&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;7286&quot; data-start=&quot;7246&quot; data-ke-size=&quot;size18&quot;&gt;Eventually, that became its own problem.&lt;/p&gt;
&lt;p data-end=&quot;7312&quot; data-start=&quot;7288&quot; data-ke-size=&quot;size18&quot;&gt;An MVP needs a boundary.&lt;/p&gt;
&lt;p data-end=&quot;7341&quot; data-start=&quot;7314&quot; data-ke-size=&quot;size18&quot;&gt;So I froze the feature set.&lt;/p&gt;
&lt;p data-end=&quot;7475&quot; data-start=&quot;7343&quot; data-ke-size=&quot;size18&quot;&gt;Some improvements now belong to the next version. That felt slightly uncomfortable, but I think that discomfort is part of shipping.&lt;/p&gt;
&lt;p data-end=&quot;7511&quot; data-start=&quot;7477&quot; data-ke-size=&quot;size18&quot;&gt;Calling an MVP done does not mean:&lt;/p&gt;
&lt;p data-end=&quot;7554&quot; data-start=&quot;7515&quot; data-ke-size=&quot;size16&quot;&gt;I cannot find anything else to improve.&lt;/p&gt;
&lt;p data-end=&quot;7565&quot; data-start=&quot;7556&quot; data-ke-size=&quot;size18&quot;&gt;It means:&lt;/p&gt;
&lt;p data-end=&quot;7696&quot; data-start=&quot;7569&quot; data-ke-size=&quot;size16&quot;&gt;The main user flow works, the serious blockers are handled, and the remaining problems no longer justify delaying this version.&lt;/p&gt;
&lt;p data-end=&quot;7756&quot; data-start=&quot;7698&quot; data-ke-size=&quot;size18&quot;&gt;That was a much harder standard to define than I expected.&lt;/p&gt;
&lt;hr data-end=&quot;7761&quot; data-start=&quot;7758&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Somewhere along the way, my notes became a release checklist&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;While building and deploying Security Lens, I kept writing down things I didn&amp;rsquo;t want to forget next time.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Build configuration. Java versions. Environment variables. Ports. Secrets. Docker. Smoke tests. Post-deployment verification.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;At first, they were just notes. Eventually, I realized I wanted a checklist I could return to before shipping my next Spring Boot project.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;I&amp;rsquo;ve now published a free edition on GitHub:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/nocklock-h/ship-your-spring-boot-mvp-free&quot;&gt;&lt;b&gt;&lt;span&gt;Ship Your Spring Boot MVP &amp;mdash; Free Checklist&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;If your application works locally and you&amp;rsquo;re wondering what to check before putting it online, that&amp;rsquo;s the situation I made it for. You can use the free edition without buying anything.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;I&amp;rsquo;m also preparing the full paid guide, &lt;/span&gt;&lt;b&gt;&lt;span&gt;Ship Your Spring Boot MVP &amp;mdash; From Localhost to Live&lt;/span&gt;&lt;/b&gt;&lt;span&gt;, with a more detailed deployment checklist and release runbook.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Security Lens is the reason I wanted this resource in the first place. The free checklist is where you can start.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-end=&quot;8392&quot; data-start=&quot;8339&quot; data-section-id=&quot;1j9k6bc&quot; data-ke-size=&quot;size26&quot;&gt;Ship Your Spring Boot MVP &amp;mdash; From Localhost to Live&lt;/h2&gt;
&lt;p data-end=&quot;8447&quot; data-start=&quot;8394&quot; data-ke-size=&quot;size18&quot;&gt;It isn&amp;rsquo;t meant to be another giant Spring Boot guide.&lt;/p&gt;
&lt;p data-end=&quot;8483&quot; data-start=&quot;8449&quot; data-ke-size=&quot;size18&quot;&gt;There are already plenty of those.&lt;/p&gt;
&lt;p data-end=&quot;8585&quot; data-start=&quot;8485&quot; data-ke-size=&quot;size18&quot;&gt;I&amp;rsquo;m building it for the point where the application already works on your machine and you&amp;rsquo;re asking:&lt;/p&gt;
&lt;p data-end=&quot;8640&quot; data-start=&quot;8589&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;What am I forgetting before I actually ship this?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;8713&quot; data-start=&quot;8642&quot; data-ke-size=&quot;size18&quot;&gt;Security Lens is the reason I wanted that checklist in the first place.&lt;/p&gt;
&lt;p data-end=&quot;8830&quot; data-start=&quot;8715&quot; data-ke-size=&quot;size18&quot;&gt;I&amp;rsquo;m also planning a smaller free version for GitHub, so developers can use the core checks without buying anything.&lt;/p&gt;
&lt;p data-end=&quot;8946&quot; data-start=&quot;8832&quot; data-ke-size=&quot;size18&quot;&gt;The full version will go deeper into the release process I now wish I had before I started deploying this project.&lt;/p&gt;
&lt;hr data-end=&quot;8951&quot; data-start=&quot;8948&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;8983&quot; data-start=&quot;8953&quot; data-section-id=&quot;17adi7&quot; data-ke-size=&quot;size26&quot;&gt;What &amp;ldquo;done&amp;rdquo; means to me now&lt;/h2&gt;
&lt;p data-end=&quot;9079&quot; data-start=&quot;8985&quot; data-ke-size=&quot;size18&quot;&gt;Before this project, I probably would have described an MVP as a smaller version of a product.&lt;/p&gt;
&lt;p data-end=&quot;9107&quot; data-start=&quot;9081&quot; data-ke-size=&quot;size18&quot;&gt;I still think that&amp;rsquo;s true.&lt;/p&gt;
&lt;p data-end=&quot;9139&quot; data-start=&quot;9109&quot; data-ke-size=&quot;size18&quot;&gt;But I would add something now.&lt;/p&gt;
&lt;p data-end=&quot;9333&quot; data-start=&quot;9141&quot; data-ke-size=&quot;size18&quot;&gt;An MVP isn&amp;rsquo;t finished when the code stops changing. It&amp;rsquo;s finished when you understand what still isn&amp;rsquo;t perfect and decide that those imperfections don&amp;rsquo;t prevent the product from doing its job.&lt;/p&gt;
&lt;p data-end=&quot;9384&quot; data-start=&quot;9335&quot; data-ke-size=&quot;size18&quot;&gt;Security Lens still has things I want to improve.&lt;/p&gt;
&lt;p data-end=&quot;9489&quot; data-start=&quot;9386&quot; data-ke-size=&quot;size18&quot;&gt;But today, for the first time, I don&amp;rsquo;t feel like I&amp;rsquo;m just running a Spring Boot project on my computer.&lt;/p&gt;
&lt;p data-end=&quot;9512&quot; data-start=&quot;9491&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;I shipped an MVP.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;9617&quot; data-start=&quot;9514&quot; data-ke-size=&quot;size18&quot;&gt;And the checklist I built while doing that is probably the part of this project I&amp;rsquo;ll reuse the longest.&lt;/p&gt;</description>
      <category>Development Notes</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/26</guid>
      <comments>https://nocklock.tistory.com/26#entry26comment</comments>
      <pubDate>Sun, 20 Sep 2026 17:23:46 +0900</pubDate>
    </item>
    <item>
      <title>Spring Boot Works Locally But Fails After Deployment: What I Checked</title>
      <link>https://nocklock.tistory.com/25</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;My Spring Boot application worked perfectly on my local machine.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;The API responded correctly.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;The frontend could call it.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;OCR was working.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;The application could detect things like phone numbers, email addresses, and image metadata.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;So naturally, I thought deployment would be the easy part.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;It wasn't.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;I&amp;rsquo;ve been building a small project called &lt;/span&gt;&lt;b&gt;&lt;span&gt;Security Lens&lt;/span&gt;&lt;/b&gt;&lt;span&gt;, a service that analyzes uploaded images and checks whether they contain potentially sensitive information.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Until recently, most of the development happened on Windows with Spring Boot running locally.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Then I decided it was time to actually ship it.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;That was when I was reminded of something simple:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;ldquo;It works on my machine&amp;rdquo; and &amp;ldquo;it works as a service&amp;rdquo; are two very different states.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Here are the things I ended up checking while preparing my Spring Boot project for deployment.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오후 05_06_21.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uOEtO/dJMcacYYlte/eoN5XiWFZKqYY9LpsneZnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uOEtO/dJMcacYYlte/eoN5XiWFZKqYY9LpsneZnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uOEtO/dJMcacYYlte/eoN5XiWFZKqYY9LpsneZnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuOEtO%2FdJMcacYYlte%2FeoN5XiWFZKqYY9LpsneZnK%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; alt=&quot;Spring Boot Works Locally&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오후 05_06_21.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;1. The port cannot always be hardcoded&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;During local development, my application was running on port 8080.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;At one point, I even ran into the classic problem:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;vhdl&quot;&gt;&lt;code&gt;Port 8080 was already in use.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;So I temporarily moved the application to another port.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Locally, that's easy.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;You can just configure:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;server.port=8081&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;and move on.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;But a deployment platform may not work like that.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Platforms such as Railway can assign a port dynamically through an environment variable.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;That means hardcoding only one port can become a problem.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;A safer configuration is something like:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;server.port=${PORT:8080}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;This means:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;use the &lt;/span&gt;&lt;span&gt;PORT&lt;/span&gt;&lt;span&gt; environment variable when it exists&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;otherwise, use &lt;/span&gt;&lt;span&gt;8080&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Locally, I can still run the application normally.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;In production, the platform can decide which port should be used.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;This is a small configuration change, but it represents a much bigger difference between local development and deployment.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;2. Environment variables matter more than I expected&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;On my development machine, a lot of things are already there.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Java is installed.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Paths exist.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Local services are running.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Configuration files are available.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;I know where everything is because I created the environment myself.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;A deployment environment knows none of that.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;If the application depends on something external, I have to explicitly think about how that dependency is configured.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;For Security Lens, this became especially important because the project wasn't just a basic CRUD application.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;It included things like:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;OCR&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;image analysis&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;EXIF metadata extraction&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;personal information detection&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;AI-assisted analysis&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;The more components you add, the easier it becomes to accidentally depend on something that only exists on your own machine.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;So before deployment, I started asking a different question.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Not:&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Does this work on my computer?&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;But:&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;What does this application assume exists?&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;That question was much more useful.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;3. Docker forced me to look at the project differently&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;I had already built the application with Gradle and Java 17.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Locally, running the Spring Boot application wasn't difficult.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Deployment made me think about the environment more explicitly.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;That's where Docker came in.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;The goal was simple:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;create an environment where the application could run without depending on the exact setup of my Windows machine.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;That meant checking things like:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;which JDK version the application needs&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;how the application is built&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;which files actually need to be included&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;which command starts the application&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;which port is exposed&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;This sounds obvious when written as a list.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;But during development, I rarely think about all of these things at the same time.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Docker made those assumptions visible.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;4. Moving from Windows to WSL created another surprise&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;While preparing the project for deployment, I started working with WSL.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Then I ran:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;and almost every file appeared to be modified.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;That was not what I wanted to see right before deployment.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;At first, it looked like something had gone seriously wrong with the repository.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;The actual problem was much less dramatic.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Windows and Linux commonly use different line endings.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Windows often uses:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;CRLF&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;while Linux usually uses:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;LF&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;So files can appear modified even when the actual source code hasn't meaningfully changed.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;I checked the difference with:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;git diff --ignore-space-at-eol --stat&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;and the situation became much clearer.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;This deserves its own post, because it was one of those problems that looks terrifying for a few minutes and turns out to have a very specific cause.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;I&amp;rsquo;ll write about that separately.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;5. &lt;/span&gt;&lt;span&gt;.gitignore&lt;/span&gt;&lt;span&gt; and &lt;/span&gt;&lt;span&gt;.dockerignore&lt;/span&gt;&lt;span&gt; are not the same thing&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;This was another detail I paid more attention to during deployment.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;I already had a &lt;/span&gt;&lt;span&gt;.gitignore&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;But Docker has a separate concern.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;When Docker builds an image, I don't necessarily want it to receive every file in the project directory.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Build outputs, IDE files, local configuration, and unnecessary directories can increase the build context or accidentally include things that should stay local.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;That's what &lt;/span&gt;&lt;span&gt;.dockerignore&lt;/span&gt;&lt;span&gt; is for.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;The distinction became clearer to me while preparing the deployment:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&gt;.gitignore
&amp;rarr; What should Git track?

.dockerignore
&amp;rarr; What should Docker receive during the build?&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;They solve different problems.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;It seems obvious now, but I hadn't really needed to care about the distinction while the application only lived on my computer.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;6. Deployment exposed assumptions hidden by local development&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;This was probably the biggest lesson.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;The application itself didn't suddenly become different.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;The environment did.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Local development hides a lot of convenience.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;My machine already knows:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;where Java is&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;which ports are available&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;which tools are installed&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;what files exist&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;how the project was configured&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;A deployment environment starts much closer to zero.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;That makes deployment useful even before anyone uses the service.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;It forces you to find the assumptions inside your application.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;For me, those assumptions started appearing one by one:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Port
Environment variables
Operating system differences
Line endings
Build configuration
Runtime dependencies
Docker context
Startup commands&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;None of these were the main feature of Security Lens.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;But all of them mattered if I wanted someone other than me to actually use it.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;7. AI helped me build faster, but I still had to understand the boundary&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;I used AI tools heavily while developing this project.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;They helped with code, debugging, configuration, and checking things I wasn't familiar with.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;That definitely made development faster.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;But deployment was a good reminder that copying a configuration without understanding it is dangerous.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;For example, something as small as:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;server.port=${PORT:8080}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;is easy to paste.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Understanding why it exists is more important.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;The same applies to Docker files, Railway configuration, Gradle settings, and environment variables.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI can suggest the next line.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;I still have to understand what happens when that line leaves my computer.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;That distinction has become more important to me as this project gets closer to being an actual product instead of just a local prototype.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;My Spring Boot deployment checklist&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;After going through this process, this is the short version of what I now check before deploying a Spring Boot application:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;inform7&quot;&gt;&lt;code&gt;[ ] Does the project build successfully from a clean environment?
[ ] Is the required Java version explicit?
[ ] Is the server port configurable?
[ ] Are secrets and environment-specific values outside the source code?
[ ] Does the application depend on any locally installed program?
[ ] Are unnecessary files excluded from the Docker build?
[ ] Is the startup command correct?
[ ] Are Windows/Linux differences causing unexpected changes?
[ ] Can I explain every production configuration I added?&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;It's not a complete production checklist.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;It's simply the checklist I wish I had before I started moving this project from my machine to an actual deployment environment.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;If you&amp;rsquo;d like a checklist to keep alongside your own project, I&amp;rsquo;ve published a free edition on GitHub:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/nocklock-h/ship-your-spring-boot-mvp-free&quot;&gt;&lt;b&gt;&lt;span&gt;Get the free Spring Boot MVP checklist&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;It grew out of the same deployment work described in this post. I&amp;rsquo;ll continue refining it as I learn more from shipping Security Lens.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;From a project to something people can actually use&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Security Lens started as a project where I wanted to detect sensitive information hidden inside images.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;For most of the development process, success meant:&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;The feature works.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Deployment changed the definition.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Now success means:&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Someone else can open it and use it without knowing anything about my development environment.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;That sounds like a small difference.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;For me, it felt like the point where the project started becoming a product.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;And that turned out to require more than writing Spring Boot code.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Development Notes</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/25</guid>
      <comments>https://nocklock.tistory.com/25#entry25comment</comments>
      <pubDate>Sun, 20 Sep 2026 17:06:50 +0900</pubDate>
    </item>
    <item>
      <title>AI가 코드를 대신 써줄수록, 나는 더 알아야 했다</title>
      <link>https://nocklock.tistory.com/15</link>
      <description>&lt;h4 data-end=&quot;72&quot; data-start=&quot;50&quot; data-ke-size=&quot;size20&quot;&gt;요즘 개발하면서 AI를 정말 많이 쓴다.&lt;/h4&gt;
&lt;h4 data-end=&quot;130&quot; data-start=&quot;74&quot; data-ke-size=&quot;size20&quot;&gt;ChatGPT로 방향을 잡고, Claude로 코드를 같이 보고, 막히는 부분이 있으면 다시 질문한다.&lt;/h4&gt;
&lt;h4 data-end=&quot;211&quot; data-start=&quot;132&quot; data-ke-size=&quot;size20&quot;&gt;예전 같았으면 검색해서 문서를 찾고, 비슷한 코드를 찾아보고, 이것저것 직접 붙여보면서 해결했을 일들을 지금은 몇 초 만에 해결할 때도 있다.&lt;/h4&gt;
&lt;h4 data-end=&quot;221&quot; data-start=&quot;213&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;221&quot; data-start=&quot;213&quot; data-ke-size=&quot;size20&quot;&gt;솔직히 편하다.&lt;/h4&gt;
&lt;h4 data-end=&quot;244&quot; data-start=&quot;223&quot; data-ke-size=&quot;size20&quot;&gt;너무 편해서 가끔은 이런 생각도 든다.&lt;/h4&gt;
&lt;h4 data-end=&quot;269&quot; data-start=&quot;246&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;개발이 이렇게 쉬워져도 되는 건가?&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 18일 오전 09_02_09.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cO6CNv/dJMcabevJxn/BsX96aRMARsL4cZmYG3Sl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cO6CNv/dJMcabevJxn/BsX96aRMARsL4cZmYG3Sl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cO6CNv/dJMcabevJxn/BsX96aRMARsL4cZmYG3Sl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcO6CNv%2FdJMcabevJxn%2FBsX96aRMARsL4cZmYG3Sl0%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; alt=&quot;검수한다&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 18일 오전 09_02_09.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-end=&quot;274&quot; data-start=&quot;271&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;297&quot; data-start=&quot;276&quot; data-ke-size=&quot;size20&quot;&gt;처음에는 그냥 만들어달라고 했다&lt;/h4&gt;
&lt;h4 data-end=&quot;331&quot; data-start=&quot;299&quot; data-ke-size=&quot;size20&quot;&gt;AI를 개발에 제대로 쓰기 시작했을 때는 질문도 단순했다.&lt;/h4&gt;
&lt;h4 data-end=&quot;358&quot; data-start=&quot;333&quot; data-ke-size=&quot;size20&quot;&gt;&amp;ldquo;Spring Boot로 이 기능 만들어줘.&amp;rdquo;&lt;/h4&gt;
&lt;h4 data-end=&quot;376&quot; data-start=&quot;360&quot; data-ke-size=&quot;size20&quot;&gt;&amp;ldquo;이 API 코드 작성해줘.&amp;rdquo;&lt;/h4&gt;
&lt;h4 data-end=&quot;406&quot; data-start=&quot;378&quot; data-ke-size=&quot;size20&quot;&gt;&amp;ldquo;JavaScript에서 이 응답 화면에 뿌려줘.&amp;rdquo;&lt;/h4&gt;
&lt;h4 data-end=&quot;426&quot; data-start=&quot;408&quot; data-ke-size=&quot;size20&quot;&gt;그러면 AI가 코드를 만들어준다.&lt;/h4&gt;
&lt;h4 data-end=&quot;445&quot; data-start=&quot;428&quot; data-ke-size=&quot;size20&quot;&gt;코드를 복사해서 넣고 실행한다.&lt;/h4&gt;
&lt;h4 data-end=&quot;475&quot; data-start=&quot;447&quot; data-ke-size=&quot;size20&quot;&gt;에러가 나면 에러 메시지를 다시 AI에게 보여준다.&lt;/h4&gt;
&lt;h4 data-end=&quot;493&quot; data-start=&quot;477&quot; data-ke-size=&quot;size20&quot;&gt;그러면 또 코드를 수정해준다.&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;528&quot; data-start=&quot;495&quot; data-ke-size=&quot;size20&quot;&gt;몇 번 반복하다 보면 실제로 돌아가는 프로그램이 만들어진다.&lt;/h4&gt;
&lt;h4 data-end=&quot;549&quot; data-start=&quot;530&quot; data-ke-size=&quot;size20&quot;&gt;처음에는 이 과정이 정말 신기했다.&lt;/h4&gt;
&lt;h4 data-end=&quot;595&quot; data-start=&quot;551&quot; data-ke-size=&quot;size20&quot;&gt;내가 예전에 몇 시간 동안 찾아봤을 문제를 몇 분 만에 해결하는 경우도 있었다.&lt;/h4&gt;
&lt;h4 data-end=&quot;633&quot; data-start=&quot;597&quot; data-ke-size=&quot;size20&quot;&gt;그런데 프로젝트가 조금씩 커지면서 이상한 문제가 생기기 시작했다.&lt;/h4&gt;
&lt;hr data-end=&quot;638&quot; data-start=&quot;635&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;668&quot; data-start=&quot;640&quot; data-ke-size=&quot;size20&quot;&gt;실행은 되는데, 내가 모르는 코드가 늘어났다&lt;/h4&gt;
&lt;h4 data-end=&quot;682&quot; data-start=&quot;670&quot; data-ke-size=&quot;size20&quot;&gt;코드가 점점 많아졌다.&lt;/h4&gt;
&lt;h4 data-end=&quot;717&quot; data-start=&quot;684&quot; data-ke-size=&quot;size20&quot;&gt;문제는 그중 일부를 내가 정확히 이해하지 못한다는 것이었다.&lt;/h4&gt;
&lt;h4 data-end=&quot;736&quot; data-start=&quot;719&quot; data-ke-size=&quot;size20&quot;&gt;왜 이 어노테이션을 사용했는지.&lt;/h4&gt;
&lt;h4 data-end=&quot;760&quot; data-start=&quot;738&quot; data-ke-size=&quot;size20&quot;&gt;왜 여기서 이 객체를 만들어서 넘기는지.&lt;/h4&gt;
&lt;h4 data-end=&quot;795&quot; data-start=&quot;762&quot; data-ke-size=&quot;size20&quot;&gt;왜 JavaScript에서 이 방식으로 데이터를 처리하는지.&lt;/h4&gt;
&lt;h4 data-end=&quot;819&quot; data-start=&quot;797&quot; data-ke-size=&quot;size20&quot;&gt;왜 이 정규식이 이 문자열을 잡아내는지.&lt;/h4&gt;
&lt;h4 data-end=&quot;836&quot; data-start=&quot;821&quot; data-ke-size=&quot;size20&quot;&gt;프로그램은 돌아가고 있었다.&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;860&quot; data-start=&quot;838&quot; data-ke-size=&quot;size20&quot;&gt;그래서 처음에는 크게 신경 쓰지 않았다.&lt;/h4&gt;
&lt;h4 data-end=&quot;890&quot; data-start=&quot;862&quot; data-ke-size=&quot;size20&quot;&gt;그런데 어느 순간 결과가 이상하게 나오기 시작했다.&lt;/h4&gt;
&lt;h4 data-end=&quot;901&quot; data-start=&quot;892&quot; data-ke-size=&quot;size20&quot;&gt;서버는 정상이다.&lt;/h4&gt;
&lt;h4 data-end=&quot;917&quot; data-start=&quot;903&quot; data-ke-size=&quot;size20&quot;&gt;API도 200 OK.&lt;/h4&gt;
&lt;h4 data-end=&quot;926&quot; data-start=&quot;919&quot; data-ke-size=&quot;size20&quot;&gt;에러도 없다.&lt;/h4&gt;
&lt;h4 data-end=&quot;940&quot; data-start=&quot;928&quot; data-ke-size=&quot;size20&quot;&gt;그런데 결과가 틀렸다.&lt;/h4&gt;
&lt;h4 data-end=&quot;956&quot; data-start=&quot;942&quot; data-ke-size=&quot;size20&quot;&gt;그때부터 문제가 시작됐다.&lt;/h4&gt;
&lt;hr data-end=&quot;961&quot; data-start=&quot;958&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;995&quot; data-start=&quot;963&quot; data-ke-size=&quot;size20&quot;&gt;AI에게 &amp;ldquo;고쳐줘&amp;rdquo;라고 하기 전에 내가 알아야 했다&lt;/h4&gt;
&lt;h4 data-end=&quot;1024&quot; data-start=&quot;997&quot; data-ke-size=&quot;size20&quot;&gt;결과가 이상하면 다시 AI에게 물어볼 수도 있다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1041&quot; data-start=&quot;1026&quot; data-ke-size=&quot;size20&quot;&gt;&amp;ldquo;이거 왜 이상하게 나와?&amp;rdquo;&lt;/h4&gt;
&lt;h4 data-end=&quot;1064&quot; data-start=&quot;1043&quot; data-ke-size=&quot;size20&quot;&gt;그리고 AI는 또 무언가를 수정해준다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1097&quot; data-start=&quot;1066&quot; data-ke-size=&quot;size20&quot;&gt;그런데 이렇게 계속하다 보면 조금 위험한 상황이 생긴다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1136&quot; data-start=&quot;1099&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;무엇이 잘못됐는지 모르는 상태에서 코드를 계속 바꾸게 된다.&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;1163&quot; data-start=&quot;1138&quot; data-ke-size=&quot;size20&quot;&gt;이번 프로젝트를 진행하면서 이걸 많이 느꼈다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1225&quot; data-start=&quot;1165&quot; data-ke-size=&quot;size20&quot;&gt;OCR 결과가 이상하게 나오거나, 개인정보가 엉뚱하게 탐지되면 어디에서 문제가 발생했는지 직접 찾아야 했다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1241&quot; data-start=&quot;1227&quot; data-ke-size=&quot;size20&quot;&gt;브라우저에서 결과를 보고,&lt;/h4&gt;
&lt;h4 data-end=&quot;1266&quot; data-start=&quot;1243&quot; data-ke-size=&quot;size20&quot;&gt;Network 탭에서 API 응답을 보고,&lt;/h4&gt;
&lt;h4 data-end=&quot;1289&quot; data-start=&quot;1268&quot; data-ke-size=&quot;size20&quot;&gt;Spring Boot 로그를 확인하고,&lt;/h4&gt;
&lt;h4 data-end=&quot;1304&quot; data-start=&quot;1291&quot; data-ke-size=&quot;size20&quot;&gt;탐지 로직으로 들어가고,&lt;/h4&gt;
&lt;h4 data-end=&quot;1328&quot; data-start=&quot;1306&quot; data-ke-size=&quot;size20&quot;&gt;필요하면 OCR 결과까지 다시 확인했다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1365&quot; data-start=&quot;1330&quot; data-ke-size=&quot;size20&quot;&gt;결국 구조를 이해하지 못하면 어디가 문제인지조차 알 수 없었다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1387&quot; data-start=&quot;1367&quot; data-ke-size=&quot;size20&quot;&gt;AI가 코드를 작성해줄 수는 있지만,&lt;/h4&gt;
&lt;h4 data-end=&quot;1430&quot; data-start=&quot;1389&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;문제가 발생했을 때 어디부터 봐야 하는지는 결국 내가 알아야 했다.&lt;/b&gt;&lt;/h4&gt;
&lt;hr data-end=&quot;1435&quot; data-start=&quot;1432&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;1467&quot; data-start=&quot;1437&quot; data-ke-size=&quot;size20&quot;&gt;코드가 돌아간다는 것은 정답이라는 뜻이 아니었다&lt;/h4&gt;
&lt;h4 data-end=&quot;1501&quot; data-start=&quot;1469&quot; data-ke-size=&quot;size20&quot;&gt;AI가 만들어준 코드 중에는 정말 잘 동작하는 것도 많다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1520&quot; data-start=&quot;1503&quot; data-ke-size=&quot;size20&quot;&gt;하지만 항상 그런 것은 아니다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1562&quot; data-start=&quot;1522&quot; data-ke-size=&quot;size20&quot;&gt;문법적으로 맞고 컴파일도 되는데 내가 원하는 동작과는 다른 경우도 있다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1586&quot; data-start=&quot;1564&quot; data-ke-size=&quot;size20&quot;&gt;더 무서운 경우는 에러조차 없는 경우다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1615&quot; data-start=&quot;1588&quot; data-ke-size=&quot;size20&quot;&gt;프로그램이 아주 자연스럽게 틀린 결과를 보여준다.&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;1650&quot; data-start=&quot;1617&quot; data-ke-size=&quot;size20&quot;&gt;그러면 개발자는 그 결과가 이상하다는 것을 알아차려야 한다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1690&quot; data-start=&quot;1652&quot; data-ke-size=&quot;size20&quot;&gt;AI가 자신 있게 만들어준 코드라고 해서 맞는 코드라는 보장은 없다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1703&quot; data-start=&quot;1692&quot; data-ke-size=&quot;size20&quot;&gt;생각해보면 당연하다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1769&quot; data-start=&quot;1705&quot; data-ke-size=&quot;size20&quot;&gt;AI는 내가 원하는 서비스를 실제로 운영해본 것도 아니고, 내가 가진 모든 맥락을 완벽하게 알고 있는 것도 아니다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1791&quot; data-start=&quot;1771&quot; data-ke-size=&quot;size20&quot;&gt;결국 마지막 판단은 개발자의 몫이다.&lt;/h4&gt;
&lt;hr data-end=&quot;1796&quot; data-start=&quot;1793&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;1830&quot; data-start=&quot;1798&quot; data-ke-size=&quot;size20&quot;&gt;그래서 AI 시대에는 공부를 덜 해도 될 줄 알았다&lt;/h4&gt;
&lt;h4 data-end=&quot;1846&quot; data-start=&quot;1832&quot; data-ke-size=&quot;size20&quot;&gt;처음에는 반대로 생각했다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1901&quot; data-start=&quot;1848&quot; data-ke-size=&quot;size20&quot;&gt;AI가 코드를 이렇게 잘 만들어주면 앞으로 개발자는 예전처럼 모든 것을 외우지 않아도 되겠다고.&lt;/h4&gt;
&lt;h4 data-end=&quot;1918&quot; data-start=&quot;1903&quot; data-ke-size=&quot;size20&quot;&gt;틀린 생각은 아닌 것 같다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1953&quot; data-start=&quot;1920&quot; data-ke-size=&quot;size20&quot;&gt;실제로 나는 예전보다 코드를 직접 타이핑하는 시간이 줄었다.&lt;/h4&gt;
&lt;h4 data-end=&quot;1982&quot; data-start=&quot;1955&quot; data-ke-size=&quot;size20&quot;&gt;하지만 이상하게도 공부해야 할 것은 더 많아졌다.&lt;/h4&gt;
&lt;h4 data-end=&quot;2037&quot; data-start=&quot;1984&quot; data-ke-size=&quot;size20&quot;&gt;왜냐하면 이제는 &lt;b&gt;코드를 작성하는 능력보다 코드를 판단하는 능력&lt;/b&gt;이 더 중요해졌기 때문이다.&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;2057&quot; data-start=&quot;2039&quot; data-ke-size=&quot;size20&quot;&gt;AI가 만들어준 설계가 괜찮은지.&lt;/h4&gt;
&lt;h4 data-end=&quot;2057&quot; data-start=&quot;2039&quot; data-ke-size=&quot;size20&quot;&gt;보안 문제가 없는지.&lt;/h4&gt;
&lt;h4 data-end=&quot;2084&quot; data-start=&quot;2072&quot; data-ke-size=&quot;size20&quot;&gt;성능상 문제가 없는지.&lt;/h4&gt;
&lt;h4 data-end=&quot;2109&quot; data-start=&quot;2086&quot; data-ke-size=&quot;size20&quot;&gt;굳이 이렇게 복잡하게 만들 필요가 있는지.&lt;/h4&gt;
&lt;h4 data-end=&quot;2124&quot; data-start=&quot;2111&quot; data-ke-size=&quot;size20&quot;&gt;다른 방식이 더 좋은지.&lt;/h4&gt;
&lt;h4 data-end=&quot;2148&quot; data-start=&quot;2126&quot; data-ke-size=&quot;size20&quot;&gt;이걸 판단하려면 결국 내가 알아야 한다.&lt;/h4&gt;
&lt;h4 data-end=&quot;2167&quot; data-start=&quot;2150&quot; data-ke-size=&quot;size20&quot;&gt;그래서 요즘 이런 생각을 한다.&lt;/h4&gt;
&lt;p data-end=&quot;2229&quot; data-start=&quot;2171&quot; data-ke-size=&quot;size16&quot;&gt;AI 때문에 개발 공부가 필요 없어지는 게 아니라&lt;br /&gt;공부해야 하는 이유가 바뀌고 있는 것은 아닐까.&lt;/p&gt;
&lt;hr data-end=&quot;2234&quot; data-start=&quot;2231&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;2265&quot; data-start=&quot;2236&quot; data-ke-size=&quot;size20&quot;&gt;내가 AI에게 질문하는 방식도 조금씩 달라졌다&lt;/h4&gt;
&lt;h4 data-end=&quot;2283&quot; data-start=&quot;2267&quot; data-ke-size=&quot;size20&quot;&gt;예전에는 주로 이런 식이었다.&lt;/h4&gt;
&lt;h4 data-end=&quot;2295&quot; data-start=&quot;2285&quot; data-ke-size=&quot;size20&quot;&gt;&amp;ldquo;이거 만들어줘.&amp;rdquo;&lt;/h4&gt;
&lt;h4 data-end=&quot;2309&quot; data-start=&quot;2297&quot; data-ke-size=&quot;size20&quot;&gt;요즘은 조금 달라졌다.&lt;/h4&gt;
&lt;h4 data-end=&quot;2340&quot; data-start=&quot;2311&quot; data-ke-size=&quot;size20&quot;&gt;&amp;ldquo;나는 이런 구조로 만들려고 하는데 문제가 있을까?&amp;rdquo;&lt;/h4&gt;
&lt;h4 data-end=&quot;2368&quot; data-start=&quot;2342&quot; data-ke-size=&quot;size20&quot;&gt;&amp;ldquo;이 코드에서 내가 놓친 예외 상황을 찾아줘.&amp;rdquo;&lt;/h4&gt;
&lt;h4 data-end=&quot;2397&quot; data-start=&quot;2370&quot; data-ke-size=&quot;size20&quot;&gt;&amp;ldquo;이 설계에서 나중에 문제가 될 부분이 있을까?&amp;rdquo;&lt;/h4&gt;
&lt;h4 data-end=&quot;2423&quot; data-start=&quot;2399&quot; data-ke-size=&quot;size20&quot;&gt;&amp;ldquo;이 코드를 더 단순하게 만들 수 있을까?&amp;rdquo;&lt;/h4&gt;
&lt;h4 data-end=&quot;2480&quot; data-start=&quot;2425&quot; data-ke-size=&quot;size20&quot;&gt;코드를 대신 작성하게 하는 것보다 &lt;b&gt;내 생각을 검증하는 용도&lt;/b&gt;로 쓰는 비중이 점점 커지고 있다.&lt;/h4&gt;
&lt;h4 data-end=&quot;2506&quot; data-start=&quot;2482&quot; data-ke-size=&quot;size20&quot;&gt;그리고 이 방식이 개인적으로 훨씬 재미있다.&lt;/h4&gt;
&lt;h4 data-end=&quot;2519&quot; data-start=&quot;2508&quot; data-ke-size=&quot;size20&quot;&gt;내가 먼저 생각하고,&lt;/h4&gt;
&lt;h4 data-end=&quot;2537&quot; data-start=&quot;2521&quot; data-ke-size=&quot;size20&quot;&gt;AI가 다른 관점을 보여주고,&lt;/h4&gt;
&lt;h4 data-end=&quot;2553&quot; data-start=&quot;2539&quot; data-ke-size=&quot;size20&quot;&gt;그걸 다시 내가 판단한다.&lt;/h4&gt;
&lt;h4 data-end=&quot;2574&quot; data-start=&quot;2555&quot; data-ke-size=&quot;size20&quot;&gt;AI에게 개발을 맡기는 게 아니라,&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;2607&quot; data-start=&quot;2576&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;AI와 같이 개발하는 느낌에 조금 더 가까워졌다.&lt;/b&gt;&lt;/h4&gt;
&lt;hr data-end=&quot;2612&quot; data-start=&quot;2609&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;2629&quot; data-start=&quot;2614&quot; data-ke-size=&quot;size20&quot;&gt;그래도 가끔은 무섭다&lt;/h4&gt;
&lt;h4 data-end=&quot;2660&quot; data-start=&quot;2631&quot; data-ke-size=&quot;size20&quot;&gt;AI가 코드를 만들어내는 속도를 보면 가끔은 무섭다.&lt;/h4&gt;
&lt;h4 data-end=&quot;2728&quot; data-start=&quot;2662&quot; data-ke-size=&quot;size20&quot;&gt;내가 몇 년 동안 배웠던 것들을 몇 초 만에 만들어내는 걸 보고 있으면 개발자의 역할이 어디까지 남을까 생각하게 된다.&lt;/h4&gt;
&lt;h4 data-end=&quot;2767&quot; data-start=&quot;2730&quot; data-ke-size=&quot;size20&quot;&gt;하지만 이번에 직접 프로젝트를 만들면서 조금 다르게 생각하게 됐다.&lt;/h4&gt;
&lt;h4 data-end=&quot;2818&quot; data-start=&quot;2769&quot; data-ke-size=&quot;size20&quot;&gt;코드를 작성하는 능력만 놓고 보면 AI가 점점 더 많은 부분을 가져갈 수 있을 것 같다.&lt;/h4&gt;
&lt;h4 data-end=&quot;2842&quot; data-start=&quot;2820&quot; data-ke-size=&quot;size20&quot;&gt;대신 어떤 문제를 해결할 것인지 정하고,&lt;/h4&gt;
&lt;h4 data-end=&quot;2863&quot; data-start=&quot;2844&quot; data-ke-size=&quot;size20&quot;&gt;어떤 구조로 만들 것인지 판단하고,&lt;/h4&gt;
&lt;h4 data-end=&quot;2878&quot; data-start=&quot;2865&quot; data-ke-size=&quot;size20&quot;&gt;이상한 결과를 발견하고,&lt;/h4&gt;
&lt;h4 data-end=&quot;2916&quot; data-start=&quot;2880&quot; data-ke-size=&quot;size20&quot;&gt;왜 그런 문제가 발생했는지 찾아가는 일은 아직 사람의 몫이 크다.&lt;/h4&gt;
&lt;h4 data-end=&quot;2947&quot; data-start=&quot;2918&quot; data-ke-size=&quot;size20&quot;&gt;그리고 그걸 잘하기 위해서는 결국 기본기가 필요하다.&lt;/h4&gt;
&lt;h4 data-end=&quot;2961&quot; data-start=&quot;2949&quot; data-ke-size=&quot;size20&quot;&gt;Java도 다시 보고,&lt;/h4&gt;
&lt;h4 data-end=&quot;2977&quot; data-start=&quot;2963&quot; data-ke-size=&quot;size20&quot;&gt;Spring도 다시 보고,&lt;/h4&gt;
&lt;h4 data-end=&quot;2988&quot; data-start=&quot;2979&quot; data-ke-size=&quot;size20&quot;&gt;HTTP도 보고,&lt;/h4&gt;
&lt;h4 data-end=&quot;2997&quot; data-start=&quot;2990&quot; data-ke-size=&quot;size20&quot;&gt;DB도 보고,&lt;/h4&gt;
&lt;h4 data-end=&quot;3016&quot; data-start=&quot;2999&quot; data-ke-size=&quot;size20&quot;&gt;네트워크도 다시 공부하게 된다.&lt;/h4&gt;
&lt;h4 data-end=&quot;3043&quot; data-start=&quot;3018&quot; data-ke-size=&quot;size20&quot;&gt;AI 덕분에 공부를 덜 하게 될 줄 알았는데,&lt;/h4&gt;
&lt;h4 data-end=&quot;3063&quot; data-start=&quot;3045&quot; data-ke-size=&quot;size20&quot;&gt;결과적으로는 다시 공부하고 있다.&lt;/h4&gt;
&lt;h4 data-end=&quot;3075&quot; data-start=&quot;3065&quot; data-ke-size=&quot;size20&quot;&gt;조금 아이러니하다.&lt;/h4&gt;
&lt;hr data-end=&quot;3080&quot; data-start=&quot;3077&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;3096&quot; data-start=&quot;3082&quot; data-ke-size=&quot;size20&quot;&gt;기술이 무서운 이유&lt;/h4&gt;
&lt;h4 data-end=&quot;3138&quot; data-start=&quot;3098&quot; data-ke-size=&quot;size20&quot;&gt;내가 기술이 무섭다고 느끼는 건 기술이 너무 빠르게 발전해서만은 아니다.&lt;/h4&gt;
&lt;h4 data-end=&quot;3168&quot; data-start=&quot;3140&quot; data-ke-size=&quot;size20&quot;&gt;오히려 더 무서운 건 &lt;b&gt;너무 편해지는 것&lt;/b&gt;이다.&lt;/h4&gt;
&lt;h4 data-end=&quot;3204&quot; data-start=&quot;3170&quot; data-ke-size=&quot;size20&quot;&gt;편리함에 익숙해지면 생각을 하지 않아도 되는 순간이 늘어난다.&lt;/h4&gt;
&lt;h4 data-end=&quot;3228&quot; data-start=&quot;3206&quot; data-ke-size=&quot;size20&quot;&gt;코드를 이해하지 않아도 복사할 수 있고,&lt;/h4&gt;
&lt;h4 data-end=&quot;3251&quot; data-start=&quot;3230&quot; data-ke-size=&quot;size20&quot;&gt;문제를 정확히 몰라도 질문할 수 있고,&lt;/h4&gt;
&lt;h4 data-end=&quot;3276&quot; data-start=&quot;3253&quot; data-ke-size=&quot;size20&quot;&gt;답이 맞는지 몰라도 일단 실행할 수 있다.&lt;/h4&gt;
&lt;h4 data-end=&quot;3300&quot; data-start=&quot;3278&quot; data-ke-size=&quot;size20&quot;&gt;그래서 오히려 조심해야 한다고 생각한다.&lt;/h4&gt;
&lt;h4 data-end=&quot;3317&quot; data-start=&quot;3302&quot; data-ke-size=&quot;size20&quot;&gt;AI를 멀리할 필요는 없다.&lt;/h4&gt;
&lt;h4 data-end=&quot;3349&quot; data-start=&quot;3319&quot; data-ke-size=&quot;size20&quot;&gt;나는 앞으로도 아마 지금보다 더 많이 사용할 것 같다.&lt;/h4&gt;
&lt;h4 data-end=&quot;3372&quot; data-start=&quot;3351&quot; data-ke-size=&quot;size20&quot;&gt;다만 한 가지는 놓치지 않으려고 한다.&lt;/h4&gt;
&lt;h4 data-end=&quot;3397&quot; data-start=&quot;3374&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;왜 이렇게 동작하는지 이해하는 것.&lt;/b&gt;&lt;/h4&gt;
&lt;h4 data-end=&quot;3418&quot; data-start=&quot;3399&quot; data-ke-size=&quot;size20&quot;&gt;요즘은 AI에게 더 많이 질문한다.&lt;/h4&gt;
&lt;h4 data-end=&quot;3430&quot; data-start=&quot;3420&quot; data-ke-size=&quot;size20&quot;&gt;그리고 이상하게도,&lt;/h4&gt;
&lt;h4 data-end=&quot;3474&quot; data-start=&quot;3432&quot; data-ke-size=&quot;size20&quot;&gt;AI를 더 많이 사용할수록&lt;br /&gt;내가 직접 공부해야 할 것도 더 많이 보인다.&lt;/h4&gt;
&lt;h4 data-end=&quot;3519&quot; data-start=&quot;3476&quot; data-ke-size=&quot;size20&quot;&gt;어쩌면 앞으로 개발자에게 필요한 능력은&lt;br /&gt;코드를 얼마나 많이 작성하느냐보다,&lt;/h4&gt;
&lt;h4 data-end=&quot;3570&quot; data-start=&quot;3521&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;AI가 만들어낸 수많은 답 중에서 무엇이 맞는지 판단할 수 있느냐&lt;/b&gt;인지도 모르겠다.&lt;/h4&gt;</description>
      <category>기술이 조금 무섭다</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/15</guid>
      <comments>https://nocklock.tistory.com/15#entry15comment</comments>
      <pubDate>Sun, 20 Sep 2026 10:02:30 +0900</pubDate>
    </item>
    <item>
      <title>기능이 된다고 제품이 되는 건 아니었다 | RE:개발자 #9</title>
      <link>https://nocklock.tistory.com/14</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;잘 돌아간다고, 제대로 돌아가는 건 아니었다.&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 18일 오전 08_55_02.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fy7X6/dJMcaaGV0M4/y9hAYvNb812fOYIvf14XT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fy7X6/dJMcaaGV0M4/y9hAYvNb812fOYIvf14XT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fy7X6/dJMcaaGV0M4/y9hAYvNb812fOYIvf14XT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFy7X6%2FdJMcaaGV0M4%2Fy9hAYvNb812fOYIvf14XT1%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; alt=&quot;테스트&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 18일 오전 08_55_02.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;div data-is-intersecting=&quot;true&quot; data-turn-id-container=&quot;request-WEB:2a01cef5-faeb-4fbf-8734-c2959ef9df08-4&quot;&gt;
&lt;div data-conversation-screenshot-content=&quot;&quot;&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5-6-thinking&quot; data-turn-start-message=&quot;true&quot; data-message-id=&quot;c39c307e-1f80-4e7f-b2a4-415213c42b75&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-end=&quot;106&quot; data-start=&quot;59&quot; data-ke-size=&quot;size16&quot;&gt;프론트 화면을 붙이고 실제 Spring Boot API까지 연결하니 꽤 그럴듯해졌다.&lt;/p&gt;
&lt;p data-end=&quot;191&quot; data-start=&quot;108&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 올리고 분석 버튼을 누르면 서버로 요청이 넘어가고, OCR을 거쳐 개인정보를 찾고, 메타데이터와 위험도를 분석한 뒤 결과가 화면에 표시됐다.&lt;/p&gt;
&lt;p data-end=&quot;224&quot; data-start=&quot;193&quot; data-ke-size=&quot;size16&quot;&gt;브라우저의 Network 탭을 열어봐도 200 OK.&lt;/p&gt;
&lt;p data-end=&quot;244&quot; data-start=&quot;226&quot; data-ke-size=&quot;size16&quot;&gt;서버 로그에도 큰 에러는 없었다.&lt;/p&gt;
&lt;p data-end=&quot;255&quot; data-start=&quot;246&quot; data-ke-size=&quot;size16&quot;&gt;처음엔 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;266&quot; data-start=&quot;257&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;됐다.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;313&quot; data-start=&quot;268&quot; data-ke-size=&quot;size16&quot;&gt;그런데 직접 여러 이미지를 넣어보기 시작하니 조금 다른 이야기가 보이기 시작했다.&lt;/p&gt;
&lt;h3 data-end=&quot;335&quot; data-start=&quot;315&quot; data-ke-size=&quot;size23&quot;&gt;에러가 없는데 결과가 이상했다&lt;/h3&gt;
&lt;p data-end=&quot;371&quot; data-start=&quot;337&quot; data-ke-size=&quot;size16&quot;&gt;이번 프로젝트에서는 사진 안에 있는 개인정보를 찾아내야 했다.&lt;/p&gt;
&lt;p data-end=&quot;444&quot; data-start=&quot;373&quot; data-ke-size=&quot;size16&quot;&gt;이름이나 전화번호, 이메일, 주소 같은 정보를 OCR로 읽고, 읽어온 문자열을 다시 분석해서 어떤 종류의 개인정보인지 판단한다.&lt;/p&gt;
&lt;p data-end=&quot;458&quot; data-start=&quot;446&quot; data-ke-size=&quot;size16&quot;&gt;흐름 자체는 단순하다.&lt;/p&gt;
&lt;p data-end=&quot;528&quot; data-start=&quot;460&quot; data-ke-size=&quot;size16&quot;&gt;사진을 올린다.&lt;br /&gt;OCR이 글자를 읽는다.&lt;br /&gt;개인정보인지 판단한다.&lt;br /&gt;위험도를 계산한다.&lt;br /&gt;결과를 화면에 보여준다.&lt;/p&gt;
&lt;p data-end=&quot;543&quot; data-start=&quot;530&quot; data-ke-size=&quot;size16&quot;&gt;여기까지는 잘 돌아갔다.&lt;/p&gt;
&lt;p data-end=&quot;575&quot; data-start=&quot;545&quot; data-ke-size=&quot;size16&quot;&gt;그런데 테스트 이미지를 하나씩 넣어보니 문제가 생겼다.&lt;/p&gt;
&lt;p data-end=&quot;665&quot; data-start=&quot;577&quot; data-ke-size=&quot;size16&quot;&gt;분명 주소가 아닌데 주소처럼 잡히기도 하고, 일반 숫자가 민감한 번호처럼 분류되기도 했다. 반대로 사람이 보기에는 개인정보인데 탐지하지 못하는 경우도 있었다.&lt;/p&gt;
&lt;p data-end=&quot;690&quot; data-start=&quot;667&quot; data-ke-size=&quot;size16&quot;&gt;재미있는 건 프로그램은 멀쩡했다는 것이다.&lt;/p&gt;
&lt;p data-end=&quot;721&quot; data-start=&quot;692&quot; data-ke-size=&quot;size16&quot;&gt;서버가 죽은 것도 아니고 예외가 발생한 것도 아니다.&lt;/p&gt;
&lt;p data-end=&quot;742&quot; data-start=&quot;723&quot; data-ke-size=&quot;size16&quot;&gt;API 응답도 정상적으로 돌아왔다.&lt;/p&gt;
&lt;p data-end=&quot;775&quot; data-start=&quot;744&quot; data-ke-size=&quot;size16&quot;&gt;그냥 &lt;b&gt;틀린 답을 아주 정상적으로 반환하고 있었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;787&quot; data-start=&quot;777&quot; data-ke-size=&quot;size16&quot;&gt;그때 다시 느꼈다.&lt;/p&gt;
&lt;blockquote data-end=&quot;827&quot; data-start=&quot;789&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;827&quot; data-start=&quot;791&quot; data-ke-size=&quot;size16&quot;&gt;에러가 나지 않는 것과 제대로 동작하는 것은 전혀 다른 문제였다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-end=&quot;847&quot; data-start=&quot;829&quot; data-ke-size=&quot;size23&quot;&gt;어디에서 틀렸는지 찾아가기&lt;/h3&gt;
&lt;p data-end=&quot;885&quot; data-start=&quot;849&quot; data-ke-size=&quot;size16&quot;&gt;결과가 이상하다고 해서 바로 코드를 수정할 수 있는 건 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;913&quot; data-start=&quot;887&quot; data-ke-size=&quot;size16&quot;&gt;먼저 어디에서 문제가 시작됐는지를 찾아야 했다.&lt;/p&gt;
&lt;p data-end=&quot;1024&quot; data-start=&quot;915&quot; data-ke-size=&quot;size16&quot;&gt;OCR이 처음부터 글자를 잘못 읽은 건지, OCR 결과는 정상인데 개인정보 판별 로직에서 잘못 분류한 건지, 서버 결과는 정상인데 JavaScript에서 화면에 잘못 표시한 건지 하나씩 확인했다.&lt;/p&gt;
&lt;p data-end=&quot;1050&quot; data-start=&quot;1026&quot; data-ke-size=&quot;size16&quot;&gt;이럴 때 다시 익숙한 화면들을 오가게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;1119&quot; data-start=&quot;1052&quot; data-ke-size=&quot;size16&quot;&gt;브라우저에서는 Network와 Console을 보고, IntelliJ에서는 Spring Boot 로그를 확인했다.&lt;/p&gt;
&lt;p data-end=&quot;1151&quot; data-start=&quot;1121&quot; data-ke-size=&quot;size16&quot;&gt;그리고 실제 API가 반환한 JSON도 계속 비교했다.&lt;/p&gt;
&lt;p data-end=&quot;1202&quot; data-start=&quot;1153&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 화면에 이상한 개인정보가 하나 표시된다면 제일 먼저 API 응답부터 확인했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;type&quot;: &quot;ADDRESS&quot;,
  &quot;value&quot;: &quot;어떤 문자열&quot;,
  &quot;confidence&quot;: 0.82
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1304&quot; data-start=&quot;1284&quot; data-ke-size=&quot;size16&quot;&gt;여기서부터 거꾸로 올라가는 식이었다.&lt;/p&gt;
&lt;p data-end=&quot;1343&quot; data-start=&quot;1306&quot; data-ke-size=&quot;size16&quot;&gt;서버가 이미 ADDRESS라고 판단했다면 화면의 문제가 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1359&quot; data-start=&quot;1345&quot; data-ke-size=&quot;size16&quot;&gt;그러면 탐지 로직을 본다.&lt;/p&gt;
&lt;p data-end=&quot;1399&quot; data-start=&quot;1361&quot; data-ke-size=&quot;size16&quot;&gt;탐지 로직에 문제가 없다면 OCR이 넘겨준 원본 문자열을 다시 본다.&lt;/p&gt;
&lt;p data-end=&quot;1454&quot; data-start=&quot;1401&quot; data-ke-size=&quot;size16&quot;&gt;생각보다 단순한 과정인데 실제 개발에서는 이런 식으로 하나씩 범위를 좁혀가는 시간이 꽤 길었다.&lt;/p&gt;
&lt;h3 data-end=&quot;1477&quot; data-start=&quot;1456&quot; data-ke-size=&quot;size23&quot;&gt;OCR이 읽었다고 끝이 아니었다&lt;/h3&gt;
&lt;p data-end=&quot;1514&quot; data-start=&quot;1479&quot; data-ke-size=&quot;size16&quot;&gt;처음 OCR을 붙였을 때는 글자를 읽어오는 것 자체가 신기했다.&lt;/p&gt;
&lt;p data-end=&quot;1545&quot; data-start=&quot;1516&quot; data-ke-size=&quot;size16&quot;&gt;사진을 넣었는데 프로그램이 그 안의 문자를 찾아낸다.&lt;/p&gt;
&lt;p data-end=&quot;1583&quot; data-start=&quot;1547&quot; data-ke-size=&quot;size16&quot;&gt;그런데 실제 서비스처럼 만들려고 하니 그 다음부터가 더 중요했다.&lt;/p&gt;
&lt;p data-end=&quot;1670&quot; data-start=&quot;1585&quot; data-ke-size=&quot;size16&quot;&gt;OCR이 문자열을 반환했다고 해서 그 문자열이 반드시 정확한 것도 아니고, 정확하게 읽었다고 해서 그것이 어떤 정보인지 바로 알 수 있는 것도 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;1689&quot; data-start=&quot;1672&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 숫자가 있다고 하자.&lt;/p&gt;
&lt;p data-end=&quot;1741&quot; data-start=&quot;1691&quot; data-ke-size=&quot;size16&quot;&gt;그게 전화번호인지, 날짜인지, 일반적인 숫자인지, 다른 식별번호의 일부인지 판단해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;1760&quot; data-start=&quot;1743&quot; data-ke-size=&quot;size16&quot;&gt;그래서 결국 이런 구조가 됐다.&lt;/p&gt;
&lt;p data-end=&quot;1808&quot; data-start=&quot;1762&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OCR &amp;rarr; 문자열 분석 &amp;rarr; 패턴 확인 &amp;rarr; 개인정보 유형 분류 &amp;rarr; 위험도 계산&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1840&quot; data-start=&quot;1810&quot; data-ke-size=&quot;size16&quot;&gt;하나의 결과가 나오기까지 생각보다 여러 단계가 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1885&quot; data-start=&quot;1842&quot; data-ke-size=&quot;size16&quot;&gt;그리고 앞 단계에서 작은 오차가 발생하면 뒤쪽 결과까지 그대로 영향을 받는다.&lt;/p&gt;
&lt;p data-end=&quot;1965&quot; data-start=&quot;1887&quot; data-ke-size=&quot;size16&quot;&gt;OCR이 글자 하나를 잘못 읽으면 정규식에 걸리지 않을 수도 있고, 반대로 우연히 특정 패턴과 비슷해져서 개인정보로 잘못 탐지될 수도 있다.&lt;/p&gt;
&lt;h3 data-end=&quot;1986&quot; data-start=&quot;1967&quot; data-ke-size=&quot;size23&quot;&gt;AI도 그냥 믿으면 안 됐다&lt;/h3&gt;
&lt;p data-end=&quot;2012&quot; data-start=&quot;1988&quot; data-ke-size=&quot;size16&quot;&gt;이번 프로젝트에서는 LLM도 사용하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;2060&quot; data-start=&quot;2014&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 AI가 분석 결과를 만들어주면 꽤 많은 부분을 해결할 수 있을 것 같았다.&lt;/p&gt;
&lt;p data-end=&quot;2077&quot; data-start=&quot;2062&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이것도 마찬가지였다.&lt;/p&gt;
&lt;p data-end=&quot;2117&quot; data-start=&quot;2079&quot; data-ke-size=&quot;size16&quot;&gt;AI가 자연스럽게 설명한다고 해서 그 결과가 항상 맞는 것은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;2220&quot; data-start=&quot;2119&quot; data-ke-size=&quot;size16&quot;&gt;그래서 AI에게 모든 판단을 맡기기보다는, 프로그램이 먼저 계산할 수 있는 것들은 최대한 코드에서 처리하고 AI는 그 결과를 바탕으로 설명하거나 보조하는 역할에 가깝게 두려고 했다.&lt;/p&gt;
&lt;p data-end=&quot;2273&quot; data-start=&quot;2222&quot; data-ke-size=&quot;size16&quot;&gt;이 과정에서 AI를 사용하는 것과 &lt;b&gt;AI에 의존하는 것&lt;/b&gt;은 조금 다르다는 생각도 들었다.&lt;/p&gt;
&lt;p data-end=&quot;2318&quot; data-start=&quot;2275&quot; data-ke-size=&quot;size16&quot;&gt;결국 서비스의 결과에 책임을 지는 건 AI가 아니라 내가 작성한 프로그램이다.&lt;/p&gt;
&lt;h3 data-end=&quot;2345&quot; data-start=&quot;2320&quot; data-ke-size=&quot;size23&quot;&gt;테스트라는 말을 조금 다르게 보게 됐다&lt;/h3&gt;
&lt;p data-end=&quot;2385&quot; data-start=&quot;2347&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 테스트라고 하면 JUnit이나 테스트 코드부터 떠올렸다.&lt;/p&gt;
&lt;p data-end=&quot;2403&quot; data-start=&quot;2387&quot; data-ke-size=&quot;size16&quot;&gt;물론 그런 테스트도 중요하다.&lt;/p&gt;
&lt;p data-end=&quot;2437&quot; data-start=&quot;2405&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이번에는 조금 더 단순한 테스트를 정말 많이 했다.&lt;/p&gt;
&lt;p data-end=&quot;2459&quot; data-start=&quot;2439&quot; data-ke-size=&quot;size16&quot;&gt;내가 직접 사용자가 되어보는 것이다.&lt;/p&gt;
&lt;p data-end=&quot;2471&quot; data-start=&quot;2461&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 올려본다.&lt;/p&gt;
&lt;p data-end=&quot;2484&quot; data-start=&quot;2473&quot; data-ke-size=&quot;size16&quot;&gt;분석 버튼을 누른다.&lt;/p&gt;
&lt;p data-end=&quot;2493&quot; data-start=&quot;2486&quot; data-ke-size=&quot;size16&quot;&gt;결과를 본다.&lt;/p&gt;
&lt;p data-end=&quot;2519&quot; data-start=&quot;2495&quot; data-ke-size=&quot;size16&quot;&gt;이상한 부분이 있으면 서버 응답을 확인한다.&lt;/p&gt;
&lt;p data-end=&quot;2528&quot; data-start=&quot;2521&quot; data-ke-size=&quot;size16&quot;&gt;로그를 본다.&lt;/p&gt;
&lt;p data-end=&quot;2539&quot; data-start=&quot;2530&quot; data-ke-size=&quot;size16&quot;&gt;코드를 수정한다.&lt;/p&gt;
&lt;p data-end=&quot;2561&quot; data-start=&quot;2541&quot; data-ke-size=&quot;size16&quot;&gt;그리고 다시 같은 이미지를 넣어본다.&lt;/p&gt;
&lt;p data-end=&quot;2594&quot; data-start=&quot;2563&quot; data-ke-size=&quot;size16&quot;&gt;Build &amp;rarr; Test &amp;rarr; Debug &amp;rarr; Repeat&lt;/p&gt;
&lt;p data-end=&quot;2629&quot; data-start=&quot;2596&quot; data-ke-size=&quot;size16&quot;&gt;대표 이미지에 넣은 문구처럼 정말 이 과정을 계속 반복했다.&lt;/p&gt;
&lt;p data-end=&quot;2698&quot; data-start=&quot;2631&quot; data-ke-size=&quot;size16&quot;&gt;신기하게도 기능을 하나 새로 만드는 것보다 이미 만들어놓은 기능을 제대로 동작하게 만드는 시간이 더 오래 걸리기도 했다.&lt;/p&gt;
&lt;h3 data-end=&quot;2719&quot; data-start=&quot;2700&quot; data-ke-size=&quot;size23&quot;&gt;그래도 이 과정이 재미있었다&lt;/h3&gt;
&lt;p data-end=&quot;2777&quot; data-start=&quot;2721&quot; data-ke-size=&quot;size16&quot;&gt;예전 회사에서는 내가 작성한 코드가 실제 사용자에게 어떻게 보이는지까지 확인하지 못한 경우도 많았다.&lt;/p&gt;
&lt;p data-end=&quot;2825&quot; data-start=&quot;2779&quot; data-ke-size=&quot;size16&quot;&gt;백엔드 기능을 만들고 API가 정상적으로 동작하면 내 역할이 끝나는 경우도 있었다.&lt;/p&gt;
&lt;p data-end=&quot;2851&quot; data-start=&quot;2827&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 처음부터 끝까지 직접 만들고 있다.&lt;/p&gt;
&lt;p data-end=&quot;2884&quot; data-start=&quot;2853&quot; data-ke-size=&quot;size16&quot;&gt;그래서 내가 만든 코드의 결과를 그대로 내가 보게 된다.&lt;/p&gt;
&lt;p data-end=&quot;2903&quot; data-start=&quot;2886&quot; data-ke-size=&quot;size16&quot;&gt;잘못 만든 것도 그대로 보인다.&lt;/p&gt;
&lt;p data-end=&quot;2931&quot; data-start=&quot;2905&quot; data-ke-size=&quot;size16&quot;&gt;조금 부끄러운 결과가 화면에 튀어나오기도 한다.&lt;/p&gt;
&lt;p data-end=&quot;2951&quot; data-start=&quot;2933&quot; data-ke-size=&quot;size16&quot;&gt;그런데 오히려 그래서 재미있었다.&lt;/p&gt;
&lt;p data-end=&quot;2965&quot; data-start=&quot;2953&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;왜 이렇게 나왔지?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;3014&quot; data-start=&quot;2967&quot; data-ke-size=&quot;size16&quot;&gt;그 질문 하나를 가지고 로그를 따라가고 코드를 찾아가다 보면 어디선가 원인이 나온다.&lt;/p&gt;
&lt;p data-end=&quot;3061&quot; data-start=&quot;3016&quot; data-ke-size=&quot;size16&quot;&gt;그리고 다시 실행했을 때 원하는 결과가 나오면 그 작은 변화가 꽤 크게 느껴졌다.&lt;/p&gt;
&lt;h3 data-end=&quot;3092&quot; data-start=&quot;3063&quot; data-ke-size=&quot;size23&quot;&gt;이제는 더 만드는 것보다, 제대로 끝내는 단계&lt;/h3&gt;
&lt;p data-end=&quot;3125&quot; data-start=&quot;3094&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트를 진행하다 보면 이상하게 할 일이 계속 생긴다.&lt;/p&gt;
&lt;p data-end=&quot;3152&quot; data-start=&quot;3127&quot; data-ke-size=&quot;size16&quot;&gt;이것도 추가하고 싶고, 저것도 개선하고 싶다.&lt;/p&gt;
&lt;p data-end=&quot;3183&quot; data-start=&quot;3154&quot; data-ke-size=&quot;size16&quot;&gt;테스트를 하면 할수록 부족한 부분도 더 많이 보인다.&lt;/p&gt;
&lt;p data-end=&quot;3224&quot; data-start=&quot;3185&quot; data-ke-size=&quot;size16&quot;&gt;아마 마음만 먹으면 며칠 동안 계속 기능을 추가할 수도 있을 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;3255&quot; data-start=&quot;3226&quot; data-ke-size=&quot;size16&quot;&gt;하지만 이번에는 여기에서 한 가지를 더 배우고 있다.&lt;/p&gt;
&lt;p data-end=&quot;3283&quot; data-start=&quot;3257&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;계속 만드는 것만이 개발은 아니라는 것.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3374&quot; data-start=&quot;3285&quot; data-ke-size=&quot;size16&quot;&gt;어디까지 만들 것인지 결정하고, 지금 만들어놓은 기능을 테스트하고, 다른 사람이 봐도 이해할 수 있도록 정리하고, 하나의 결과물로 끝내는 과정도 개발의 일부다.&lt;/p&gt;
&lt;p data-end=&quot;3403&quot; data-start=&quot;3376&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 프로그램이 실행되는 것만으로 꽤 기뻤다.&lt;/p&gt;
&lt;p data-end=&quot;3420&quot; data-start=&quot;3405&quot; data-ke-size=&quot;size16&quot;&gt;지금은 조금 욕심이 생겼다.&lt;/p&gt;
&lt;p data-end=&quot;3437&quot; data-start=&quot;3422&quot; data-ke-size=&quot;size16&quot;&gt;실행되는 프로그램이 아니라,&lt;/p&gt;
&lt;p data-end=&quot;3465&quot; data-start=&quot;3439&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;제대로 동작하는 프로그램을 만들고 싶다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3500&quot; data-start=&quot;3467&quot; data-ke-size=&quot;size16&quot;&gt;그리고 이제 이번 프로젝트도 슬슬 마지막 단계로 가고 있다.&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;3571&quot; data-start=&quot;3502&quot; data-ke-size=&quot;size16&quot;&gt;다음 편에서는 코드를 더 작성하는 이야기가 아니라,&lt;br /&gt;&lt;b&gt;만들어놓은 프로젝트를 어떻게 끝내는지&lt;/b&gt;에 대해 적어보려고 한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/14</guid>
      <comments>https://nocklock.tistory.com/14#entry14comment</comments>
      <pubDate>Sun, 20 Sep 2026 09:56:03 +0900</pubDate>
    </item>
    <item>
      <title>Spring Boot Docker 배포 방법 &amp;mdash; Windows/WSL부터 Railway까지 직접 해보며 막힌 것들</title>
      <link>https://nocklock.tistory.com/24</link>
      <description>&lt;p data-end=&quot;277&quot; data-start=&quot;235&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot 프로젝트를 어느 정도 만들고 나니 다음 문제가 생겼다.&lt;/p&gt;
&lt;p data-end=&quot;316&quot; data-start=&quot;279&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내 컴퓨터에서는 잘 되는데, 다른 사람은 사용할 수 없었다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;springboot_docker_nocklock_logo_fixed.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d5qzpQ/dJMcaf2nso8/zD9kRamJ2NywQNqpyOMrek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d5qzpQ/dJMcaf2nso8/zD9kRamJ2NywQNqpyOMrek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d5qzpQ/dJMcaf2nso8/zD9kRamJ2NywQNqpyOMrek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd5qzpQ%2FdJMcaf2nso8%2FzD9kRamJ2NywQNqpyOMrek%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; alt=&quot;Deploy Method&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;springboot_docker_nocklock_logo_fixed.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;369&quot; data-start=&quot;318&quot; data-ke-size=&quot;size16&quot;&gt;localhost에서 잘 동작하는 것과 인터넷에서 실제로 서비스되는 건 다른 이야기였다.&lt;/p&gt;
&lt;p data-end=&quot;384&quot; data-start=&quot;371&quot; data-ke-size=&quot;size16&quot;&gt;결국 배포를 해야 했다.&lt;/p&gt;
&lt;p data-end=&quot;390&quot; data-start=&quot;386&quot; data-ke-size=&quot;size16&quot;&gt;처음에는&lt;/p&gt;
&lt;blockquote data-end=&quot;442&quot; data-start=&quot;392&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;442&quot; data-start=&quot;394&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot 프로젝트니까 서버에 jar 파일 올리고 실행하면 되는 거 아닌가?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;453&quot; data-start=&quot;444&quot; data-ke-size=&quot;size16&quot;&gt;정도로 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;501&quot; data-start=&quot;455&quot; data-ke-size=&quot;size16&quot;&gt;틀린 말은 아니지만, 직접 배포해보니 그 사이에 신경 써야 할 게 생각보다 많았다.&lt;/p&gt;
&lt;p data-end=&quot;576&quot; data-start=&quot;503&quot; data-ke-size=&quot;size16&quot;&gt;이번 글에서는 내가 Spring Boot 프로젝트를 Docker로 묶고 실제 배포까지 진행하면서 확인했던 내용을 정리해보려고 한다.&lt;/p&gt;
&lt;p data-end=&quot;630&quot; data-start=&quot;578&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트 자체의 기능보다는 &lt;b&gt;Spring Boot + Docker 배포 과정&lt;/b&gt;에 집중했다.&lt;/p&gt;
&lt;hr data-end=&quot;635&quot; data-start=&quot;632&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;650&quot; data-start=&quot;637&quot; data-ke-size=&quot;size26&quot;&gt;전체 흐름부터 보면&lt;/h2&gt;
&lt;p data-end=&quot;670&quot; data-start=&quot;652&quot; data-ke-size=&quot;size16&quot;&gt;내가 진행한 흐름은 대략 이랬다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;Spring Boot
    &amp;darr;
Gradle Build
    &amp;darr;
Docker Image
    &amp;darr;
GitHub
    &amp;darr;
Railway
    &amp;darr;
외부 URL&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;790&quot; data-start=&quot;775&quot; data-ke-size=&quot;size16&quot;&gt;개발 환경은 다음과 같았다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;Java 17
Spring Boot
Gradle
Windows
WSL Ubuntu
Docker
Git / GitHub
Railway&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;943&quot; data-start=&quot;879&quot; data-ke-size=&quot;size16&quot;&gt;로컬에서는 IntelliJ와 Windows를 주로 사용했고, 배포를 준비하면서 WSL Ubuntu도 같이 사용했다.&lt;/p&gt;
&lt;hr data-end=&quot;948&quot; data-start=&quot;945&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;982&quot; data-start=&quot;950&quot;&gt;1. 먼저 Spring Boot 빌드가 되는지 확인한다&lt;/h1&gt;
&lt;p data-end=&quot;1024&quot; data-start=&quot;984&quot; data-ke-size=&quot;size16&quot;&gt;Docker부터 만들기 전에 제일 먼저 확인해야 할 건 의외로 단순하다.&lt;/p&gt;
&lt;p data-end=&quot;1061&quot; data-start=&quot;1026&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Docker 없이 프로젝트 자체가 정상적으로 빌드되는가?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1104&quot; data-start=&quot;1063&quot; data-ke-size=&quot;size16&quot;&gt;Gradle 프로젝트라면 프로젝트 루트에서 다음 명령어를 실행할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1114&quot; data-start=&quot;1106&quot; data-ke-size=&quot;size16&quot;&gt;Windows:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;gradlew.bat clean build&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1173&quot; data-start=&quot;1153&quot; data-ke-size=&quot;size16&quot;&gt;Linux / WSL / macOS:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;excel&quot;&gt;&lt;code&gt;./gradlew clean build&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1239&quot; data-start=&quot;1210&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot 실행용 jar만 만들고 싶다면:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;excel&quot;&gt;&lt;code&gt;./gradlew clean bootJar&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1316&quot; data-start=&quot;1278&quot; data-ke-size=&quot;size16&quot;&gt;빌드가 정상적으로 끝나면 보통 다음 위치에 jar 파일이 만들어진다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;build/libs/&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1349&quot; data-start=&quot;1343&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;build/libs/my-app-0.0.1-SNAPSHOT.jar&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1467&quot; data-start=&quot;1401&quot; data-ke-size=&quot;size16&quot;&gt;여기서부터 문제가 생긴다면 Docker 문제를 보기 전에 &lt;b&gt;Spring Boot 빌드 오류부터 해결하는 게 낫다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1472&quot; data-start=&quot;1469&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1492&quot; data-start=&quot;1474&quot;&gt;2. Java 버전도 확인했다&lt;/h1&gt;
&lt;p data-end=&quot;1520&quot; data-start=&quot;1494&quot; data-ke-size=&quot;size16&quot;&gt;내 프로젝트는 Java 17을 사용하고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1555&quot; data-start=&quot;1522&quot; data-ke-size=&quot;size16&quot;&gt;Gradle에서도 toolchain을 지정해두는 편이 좋다.&lt;/p&gt;
&lt;p data-end=&quot;1563&quot; data-start=&quot;1557&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1743&quot; data-start=&quot;1664&quot; data-ke-size=&quot;size16&quot;&gt;로컬에서는 Java 17인데 Docker 안에서는 Java 21이라든지, 반대로 더 낮은 버전을 사용하면 예상하지 못한 문제가 생길 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1781&quot; data-start=&quot;1745&quot; data-ke-size=&quot;size16&quot;&gt;그래서 Docker 이미지의 Java 버전도 프로젝트와 맞춰줬다.&lt;/p&gt;
&lt;hr data-end=&quot;1786&quot; data-start=&quot;1783&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1807&quot; data-start=&quot;1788&quot;&gt;3. Dockerfile 만들기&lt;/h1&gt;
&lt;p data-end=&quot;1869&quot; data-start=&quot;1809&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot jar를 실행하는 가장 단순한 형태의 Dockerfile은 이런 식으로 만들 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;FROM eclipse-temurin:17-jdk

WORKDIR /app

COPY build/libs/*.jar app.jar

EXPOSE 8080

ENTRYPOINT [&quot;java&quot;, &quot;-jar&quot;, &quot;app.jar&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2029&quot; data-start=&quot;2016&quot; data-ke-size=&quot;size16&quot;&gt;하나씩 보면 별것 없다.&lt;/p&gt;
&lt;h3 data-end=&quot;2041&quot; data-start=&quot;2031&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;FROM&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;FROM eclipse-temurin:17-jdk&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2113&quot; data-start=&quot;2090&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너 안에서 사용할 Java 환경이다.&lt;/p&gt;
&lt;p data-end=&quot;2147&quot; data-start=&quot;2115&quot; data-ke-size=&quot;size16&quot;&gt;내 프로젝트가 Java 17이었기 때문에 17을 사용했다.&lt;/p&gt;
&lt;hr data-end=&quot;2152&quot; data-start=&quot;2149&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2167&quot; data-start=&quot;2154&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;WORKDIR&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;WORKDIR /app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2225&quot; data-start=&quot;2201&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너 안에서 작업할 디렉터리를 지정한다.&lt;/p&gt;
&lt;hr data-end=&quot;2230&quot; data-start=&quot;2227&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2242&quot; data-start=&quot;2232&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;COPY&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;COPY build/libs/*.jar app.jar&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2334&quot; data-start=&quot;2293&quot; data-ke-size=&quot;size16&quot;&gt;Gradle이 만들어준 jar 파일을 Docker 이미지 안으로 복사한다.&lt;/p&gt;
&lt;hr data-end=&quot;2339&quot; data-start=&quot;2336&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2353&quot; data-start=&quot;2341&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;EXPOSE&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;EXPOSE 8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2412&quot; data-start=&quot;2386&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot가 사용할 포트를 표시한다.&lt;/p&gt;
&lt;p data-end=&quot;2433&quot; data-start=&quot;2414&quot; data-ke-size=&quot;size16&quot;&gt;다만 여기서 하나 주의할 게 있다.&lt;/p&gt;
&lt;p data-end=&quot;2484&quot; data-start=&quot;2435&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;EXPOSE를 적었다고 자동으로 인터넷에서 8080 포트가 열리는 건 아니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2494&quot; data-start=&quot;2486&quot; data-ke-size=&quot;size16&quot;&gt;Docker에게&lt;/p&gt;
&lt;blockquote data-end=&quot;2520&quot; data-start=&quot;2496&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2520&quot; data-start=&quot;2498&quot; data-ke-size=&quot;size16&quot;&gt;이 애플리케이션은 이 포트를 사용합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2538&quot; data-start=&quot;2522&quot; data-ke-size=&quot;size16&quot;&gt;라고 알려주는 의미에 가깝다.&lt;/p&gt;
&lt;hr data-end=&quot;2543&quot; data-start=&quot;2540&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2561&quot; data-start=&quot;2545&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;ENTRYPOINT&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;ENTRYPOINT [&quot;java&quot;, &quot;-jar&quot;, &quot;app.jar&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2658&quot; data-start=&quot;2621&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너가 실행될 때 Spring Boot 애플리케이션을 실행한다.&lt;/p&gt;
&lt;hr data-end=&quot;2663&quot; data-start=&quot;2660&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2687&quot; data-start=&quot;2665&quot;&gt;4. 여기서 처음 실수하기 쉬운 부분&lt;/h1&gt;
&lt;p data-end=&quot;2714&quot; data-start=&quot;2689&quot; data-ke-size=&quot;size16&quot;&gt;위 Dockerfile에는 전제가 하나 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;build/libs/*.jar&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2765&quot; data-start=&quot;2746&quot; data-ke-size=&quot;size16&quot;&gt;파일이 &lt;b&gt;이미 존재해야 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2788&quot; data-start=&quot;2767&quot; data-ke-size=&quot;size16&quot;&gt;즉 Docker 이미지부터 만들기 전에&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;excel&quot;&gt;&lt;code&gt;./gradlew clean bootJar&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2837&quot; data-start=&quot;2827&quot; data-ke-size=&quot;size16&quot;&gt;를 실행해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;2880&quot; data-start=&quot;2839&quot; data-ke-size=&quot;size16&quot;&gt;그렇지 않으면 Docker 빌드 과정에서 이런 류의 오류를 만날 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;COPY failed&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2909&quot; data-start=&quot;2907&quot; data-ke-size=&quot;size16&quot;&gt;또는&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;no source files were specified&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2987&quot; data-start=&quot;2955&quot; data-ke-size=&quot;size16&quot;&gt;결국 Docker가 복사할 jar 파일을 못 찾는 것이다.&lt;/p&gt;
&lt;p data-end=&quot;2997&quot; data-start=&quot;2989&quot; data-ke-size=&quot;size16&quot;&gt;그래서 순서는:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;excel&quot;&gt;&lt;code&gt;./gradlew clean bootJar&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3040&quot; data-start=&quot;3036&quot; data-ke-size=&quot;size16&quot;&gt;그다음:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;docker build -t my-spring-app .&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3104&quot; data-start=&quot;3087&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 잡는 게 이해하기 쉽다.&lt;/p&gt;
&lt;hr data-end=&quot;3109&quot; data-start=&quot;3106&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3137&quot; data-start=&quot;3111&quot;&gt;&lt;span&gt;5. .dockerignore도 만들었다&lt;/span&gt;&lt;/h1&gt;
&lt;p data-end=&quot;3159&quot; data-start=&quot;3139&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 굳이 이게 필요한가 싶었다.&lt;/p&gt;
&lt;p data-end=&quot;3195&quot; data-start=&quot;3161&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트 전체를 Docker에 넣으면 되는 거 아닌가 싶었다.&lt;/p&gt;
&lt;p data-end=&quot;3235&quot; data-start=&quot;3197&quot; data-ke-size=&quot;size16&quot;&gt;그런데 실제로는 Docker 이미지에 필요 없는 파일이 굉장히 많다.&lt;/p&gt;
&lt;p data-end=&quot;3272&quot; data-start=&quot;3237&quot; data-ke-size=&quot;size16&quot;&gt;그래서 프로젝트 루트에 .dockerignore를 만들었다.&lt;/p&gt;
&lt;p data-end=&quot;3280&quot; data-start=&quot;3274&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;.git
.gradle
.idea
*.log
.env&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3349&quot; data-start=&quot;3325&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트에 따라서는 다음도 제외할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;node_modules&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3390&quot; data-start=&quot;3377&quot; data-ke-size=&quot;size16&quot;&gt;다만 주의할 점이 있다.&lt;/p&gt;
&lt;p data-end=&quot;3410&quot; data-start=&quot;3392&quot; data-ke-size=&quot;size16&quot;&gt;앞에서 만든 Dockerfile이&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;COPY build/libs/*.jar app.jar&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3513&quot; data-start=&quot;3461&quot; data-ke-size=&quot;size16&quot;&gt;방식이라면 build/ 폴더 전체를 .dockerignore에서 제외해버리면 안 된다.&lt;/p&gt;
&lt;p data-end=&quot;3541&quot; data-start=&quot;3515&quot; data-ke-size=&quot;size16&quot;&gt;Docker가 jar를 복사해야 하기 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;3572&quot; data-start=&quot;3543&quot; data-ke-size=&quot;size16&quot;&gt;이 부분은 Dockerfile 방식에 따라 달라진다.&lt;/p&gt;
&lt;hr data-end=&quot;3577&quot; data-start=&quot;3574&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3604&quot; data-start=&quot;3579&quot;&gt;6. Docker 이미지를 직접 만들어본다&lt;/h1&gt;
&lt;p data-end=&quot;3639&quot; data-start=&quot;3606&quot; data-ke-size=&quot;size16&quot;&gt;Dockerfile이 준비됐다면 프로젝트 루트에서 실행한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;docker build -t my-spring-app .&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3701&quot; data-start=&quot;3686&quot; data-ke-size=&quot;size16&quot;&gt;마지막의 .도 중요하다.&lt;/p&gt;
&lt;p data-end=&quot;3744&quot; data-start=&quot;3703&quot; data-ke-size=&quot;size16&quot;&gt;현재 디렉터리를 Docker build context로 사용한다는 의미다.&lt;/p&gt;
&lt;p data-end=&quot;3766&quot; data-start=&quot;3746&quot; data-ke-size=&quot;size16&quot;&gt;정상적으로 끝나면 이미지가 생성된다.&lt;/p&gt;
&lt;p data-end=&quot;3772&quot; data-start=&quot;3768&quot; data-ke-size=&quot;size16&quot;&gt;확인은:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;docker images&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;3804&quot; data-start=&quot;3801&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3821&quot; data-start=&quot;3806&quot;&gt;7. 컨테이너 실행해보기&lt;/h1&gt;
&lt;p data-end=&quot;3863&quot; data-start=&quot;3823&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 만들었다고 바로 배포로 넘어가지 않고 로컬에서 먼저 실행해봤다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;docker run -p 8080:8080 my-spring-app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3919&quot; data-start=&quot;3916&quot; data-ke-size=&quot;size16&quot;&gt;여기서&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;8080:8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3945&quot; data-start=&quot;3944&quot; data-ke-size=&quot;size16&quot;&gt;은&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;내 컴퓨터 포트 : 컨테이너 포트&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3988&quot; data-start=&quot;3979&quot; data-ke-size=&quot;size16&quot;&gt;라고 보면 된다.&lt;/p&gt;
&lt;p data-end=&quot;3997&quot; data-start=&quot;3990&quot; data-ke-size=&quot;size16&quot;&gt;브라우저에서:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;http://localhost:8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4070&quot; data-start=&quot;4034&quot; data-ke-size=&quot;size16&quot;&gt;으로 접속해서 정상적으로 Spring Boot가 뜨는지 확인한다.&lt;/p&gt;
&lt;hr data-end=&quot;4075&quot; data-start=&quot;4072&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;4102&quot; data-start=&quot;4077&quot;&gt;8. 로컬에서 8080 포트 충돌도 있었다&lt;/h1&gt;
&lt;p data-end=&quot;4144&quot; data-start=&quot;4104&quot; data-ke-size=&quot;size16&quot;&gt;개발하면서 이미 다른 프로세스가 8080을 사용하고 있는 경우도 있었다.&lt;/p&gt;
&lt;p data-end=&quot;4171&quot; data-start=&quot;4146&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot에서는 흔히 보는 문제다.&lt;/p&gt;
&lt;p data-end=&quot;4179&quot; data-start=&quot;4173&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;vhdl&quot;&gt;&lt;code&gt;Port 8080 was already in use&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4259&quot; data-start=&quot;4223&quot; data-ke-size=&quot;size16&quot;&gt;이럴 때는 기존 프로세스를 종료하거나 다른 포트를 사용하면 된다.&lt;/p&gt;
&lt;p data-end=&quot;4276&quot; data-start=&quot;4261&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot에서는:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;server.port=8081&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4325&quot; data-start=&quot;4314&quot; data-ke-size=&quot;size16&quot;&gt;처럼 바꿀 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;4340&quot; data-start=&quot;4327&quot; data-ke-size=&quot;size16&quot;&gt;Docker 실행에서도:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;docker run -p 8081:8080 my-spring-app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4405&quot; data-start=&quot;4393&quot; data-ke-size=&quot;size16&quot;&gt;처럼 사용할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;4410&quot; data-start=&quot;4407&quot; data-ke-size=&quot;size16&quot;&gt;그러면&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;localhost:8081&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4473&quot; data-start=&quot;4440&quot; data-ke-size=&quot;size16&quot;&gt;로 접속하지만 컨테이너 안에서는 여전히 8080을 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;4492&quot; data-start=&quot;4475&quot; data-ke-size=&quot;size16&quot;&gt;이걸 처음 보면 조금 헷갈린다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;basic&quot;&gt;&lt;code&gt;8081 &amp;rarr; 내 PC
8080 &amp;rarr; Docker Container&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4555&quot; data-start=&quot;4543&quot; data-ke-size=&quot;size16&quot;&gt;라고 생각하면 편했다.&lt;/p&gt;
&lt;hr data-end=&quot;4560&quot; data-start=&quot;4557&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;4597&quot; data-start=&quot;4562&quot;&gt;9. Windows에서 WSL로 넘어가니 Git이 이상해졌다&lt;/h1&gt;
&lt;p data-end=&quot;4648&quot; data-start=&quot;4599&quot; data-ke-size=&quot;size16&quot;&gt;배포 준비를 하면서 Windows에서 작업하던 프로젝트를 WSL Ubuntu에서 열었다.&lt;/p&gt;
&lt;p data-end=&quot;4664&quot; data-start=&quot;4650&quot; data-ke-size=&quot;size16&quot;&gt;그리고 평소처럼 실행했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4737&quot; data-start=&quot;4690&quot; data-ke-size=&quot;size16&quot;&gt;그런데 갑자기 내가 건드리지 않은 수많은 파일이 전부 modified로 표시됐다.&lt;/p&gt;
&lt;p data-end=&quot;4759&quot; data-start=&quot;4739&quot; data-ke-size=&quot;size16&quot;&gt;순간 프로젝트를 망가뜨린 줄 알았다.&lt;/p&gt;
&lt;p data-end=&quot;4805&quot; data-start=&quot;4761&quot; data-ke-size=&quot;size16&quot;&gt;원인은 코드 변경이 아니라 &lt;b&gt;Windows와 Linux의 줄바꿈 차이&lt;/b&gt;였다.&lt;/p&gt;
&lt;p data-end=&quot;4821&quot; data-start=&quot;4807&quot; data-ke-size=&quot;size16&quot;&gt;Windows에서는 주로:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;CRLF&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4850&quot; data-start=&quot;4841&quot; data-ke-size=&quot;size16&quot;&gt;Linux에서는:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;LF&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4875&quot; data-start=&quot;4868&quot; data-ke-size=&quot;size16&quot;&gt;를 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;4917&quot; data-start=&quot;4877&quot; data-ke-size=&quot;size16&quot;&gt;Git에서는 이 차이 때문에 파일 전체가 변경된 것처럼 보일 수 있었다.&lt;/p&gt;
&lt;p data-end=&quot;4947&quot; data-start=&quot;4919&quot; data-ke-size=&quot;size16&quot;&gt;실제 변경만 확인하기 위해 내가 사용했던 명령어가:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;git diff --ignore-space-at-eol --stat&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5004&quot; data-start=&quot;5000&quot; data-ke-size=&quot;size16&quot;&gt;이었다.&lt;/p&gt;
&lt;p data-end=&quot;5054&quot; data-start=&quot;5006&quot; data-ke-size=&quot;size16&quot;&gt;결과를 보니 실제 변경 파일은 .dockerignore, 배포 설정 파일 정도였다.&lt;/p&gt;
&lt;p data-end=&quot;5077&quot; data-start=&quot;5056&quot; data-ke-size=&quot;size16&quot;&gt;Docker 자체의 문제는 아니었지만,&lt;/p&gt;
&lt;p data-end=&quot;5141&quot; data-start=&quot;5079&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Windows + WSL + Git + Docker 조합으로 작업한다면 한 번쯤 만날 수 있는 문제&lt;/b&gt;였다.&lt;/p&gt;
&lt;p data-end=&quot;5159&quot; data-start=&quot;5143&quot; data-ke-size=&quot;size16&quot;&gt;이건 별도 글로도 정리해뒀다.&lt;/p&gt;
&lt;hr data-end=&quot;5164&quot; data-start=&quot;5161&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;5197&quot; data-start=&quot;5166&quot;&gt;10. 배포 환경에서는 PORT 처리를 확인해야 한다&lt;/h1&gt;
&lt;p data-end=&quot;5207&quot; data-start=&quot;5199&quot; data-ke-size=&quot;size16&quot;&gt;로컬에서는 보통&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;server.port=8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5267&quot; data-start=&quot;5245&quot; data-ke-size=&quot;size16&quot;&gt;처럼 고정해서 사용해도 큰 문제가 없다.&lt;/p&gt;
&lt;p data-end=&quot;5314&quot; data-start=&quot;5269&quot; data-ke-size=&quot;size16&quot;&gt;그런데 클라우드 배포 플랫폼에서는 실행할 포트를 환경변수로 전달하는 경우가 있다.&lt;/p&gt;
&lt;p data-end=&quot;5348&quot; data-start=&quot;5316&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot에서는 이런 식으로 처리해두면 편하다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;server.port=${PORT:8080}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5402&quot; data-start=&quot;5394&quot; data-ke-size=&quot;size16&quot;&gt;뜻은 간단하다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;PORT 환경변수가 있으면 &amp;rarr; 그 값 사용
없으면 &amp;rarr; 8080 사용&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5466&quot; data-start=&quot;5455&quot; data-ke-size=&quot;size16&quot;&gt;로컬에서는 8080,&lt;/p&gt;
&lt;p data-end=&quot;5504&quot; data-start=&quot;5468&quot; data-ke-size=&quot;size16&quot;&gt;배포 환경에서 PORT가 주어지면 해당 포트를 사용하게 된다.&lt;/p&gt;
&lt;p data-end=&quot;5535&quot; data-start=&quot;5506&quot; data-ke-size=&quot;size16&quot;&gt;클라우드 환경으로 넘어갈 때 확인해볼 만한 부분이다.&lt;/p&gt;
&lt;hr data-end=&quot;5540&quot; data-start=&quot;5537&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;5559&quot; data-start=&quot;5542&quot;&gt;11. GitHub에 올리기&lt;/h1&gt;
&lt;p data-end=&quot;5594&quot; data-start=&quot;5561&quot; data-ke-size=&quot;size16&quot;&gt;Docker 관련 파일까지 준비한 뒤 GitHub에 올렸다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;git add .
git commit -m &quot;feat: add docker deployment config&quot;
git push origin main&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5724&quot; data-start=&quot;5691&quot; data-ke-size=&quot;size16&quot;&gt;여기서도 바로 push하기 전에 한 번 확인하는 편이 좋다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5810&quot; data-start=&quot;5750&quot; data-ke-size=&quot;size16&quot;&gt;특히 .env 같은 환경변수 파일이나 API Key가 들어 있는 파일이 올라가지 않았는지 확인해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;5873&quot; data-start=&quot;5812&quot; data-ke-size=&quot;size16&quot;&gt;.env는 일반적으로 .gitignore와 .dockerignore 둘 다 확인하는 편이 안전하다.&lt;/p&gt;
&lt;hr data-end=&quot;5878&quot; data-start=&quot;5875&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;5904&quot; data-start=&quot;5880&quot;&gt;12. Railway와 GitHub 연결&lt;/h1&gt;
&lt;p data-end=&quot;5931&quot; data-start=&quot;5906&quot; data-ke-size=&quot;size16&quot;&gt;나는 실제 배포에는 Railway를 사용했다.&lt;/p&gt;
&lt;p data-end=&quot;5947&quot; data-start=&quot;5933&quot; data-ke-size=&quot;size16&quot;&gt;전체 흐름은 꽤 단순했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;mathematica&quot;&gt;&lt;code&gt;GitHub Repository
        &amp;darr;
Railway
        &amp;darr;
Build
        &amp;darr;
Docker Image
        &amp;darr;
Deploy
        &amp;darr;
Public URL&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6122&quot; data-start=&quot;6075&quot; data-ke-size=&quot;size16&quot;&gt;GitHub 저장소를 Railway와 연결하면 소스 코드를 가져와 빌드하고 배포한다.&lt;/p&gt;
&lt;p data-end=&quot;6157&quot; data-start=&quot;6124&quot; data-ke-size=&quot;size16&quot;&gt;Dockerfile이 있으면 이를 기반으로 빌드할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;6210&quot; data-start=&quot;6159&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 화면에 Build, Deploy 같은 상태가 뜨는 걸 보면서 그냥 기다렸다.&lt;/p&gt;
&lt;p data-end=&quot;6232&quot; data-start=&quot;6212&quot; data-ke-size=&quot;size16&quot;&gt;로컬 개발과 가장 달랐던 순간이었다.&lt;/p&gt;
&lt;p data-end=&quot;6261&quot; data-start=&quot;6234&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터에서 내가 명령어를 입력하는 게 아니라,&lt;/p&gt;
&lt;p data-end=&quot;6294&quot; data-start=&quot;6263&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다른 서버가 내 코드를 가져가서 빌드하고 있었다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;6299&quot; data-start=&quot;6296&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;6332&quot; data-start=&quot;6301&quot;&gt;13. Build 성공이 Deploy 성공은 아니었다&lt;/h1&gt;
&lt;p data-end=&quot;6356&quot; data-start=&quot;6334&quot; data-ke-size=&quot;size16&quot;&gt;여기서도 하나 구분해서 보는 게 좋았다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;Build 성공&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6381&quot; data-start=&quot;6380&quot; data-ke-size=&quot;size16&quot;&gt;과&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;서비스 정상 실행&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6418&quot; data-start=&quot;6406&quot; data-ke-size=&quot;size16&quot;&gt;은 같은 말이 아니다.&lt;/p&gt;
&lt;p data-end=&quot;6472&quot; data-start=&quot;6420&quot; data-ke-size=&quot;size16&quot;&gt;Docker 이미지를 정상적으로 만들었어도 Spring Boot 실행 중 오류가 날 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;6480&quot; data-start=&quot;6474&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;환경변수 누락
DB 연결 실패
포트 설정 문제
Java 실행 오류
ApplicationContext 시작 실패&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6568&quot; data-start=&quot;6557&quot; data-ke-size=&quot;size16&quot;&gt;등이 있을 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;6637&quot; data-start=&quot;6570&quot; data-ke-size=&quot;size16&quot;&gt;그래서 Railway나 다른 배포 플랫폼에서도 &lt;b&gt;Build 로그와 Runtime 로그를 따로 보는 습관&lt;/b&gt;이 필요하다.&lt;/p&gt;
&lt;p data-end=&quot;6665&quot; data-start=&quot;6639&quot; data-ke-size=&quot;size16&quot;&gt;단순히 초록색 체크 하나 떴다고 끝은 아니었다.&lt;/p&gt;
&lt;hr data-end=&quot;6670&quot; data-start=&quot;6667&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;6703&quot; data-start=&quot;6672&quot;&gt;14. localhost가 아닌 URL이 처음 열렸다&lt;/h1&gt;
&lt;p data-end=&quot;6732&quot; data-start=&quot;6705&quot; data-ke-size=&quot;size16&quot;&gt;배포가 정상적으로 끝난 뒤 외부 URL이 생겼다.&lt;/p&gt;
&lt;p data-end=&quot;6742&quot; data-start=&quot;6734&quot; data-ke-size=&quot;size16&quot;&gt;그동안은 계속:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;localhost&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6770&quot; data-start=&quot;6767&quot; data-ke-size=&quot;size16&quot;&gt;였다.&lt;/p&gt;
&lt;p data-end=&quot;6802&quot; data-start=&quot;6772&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이번에는 인터넷 주소를 통해 접속할 수 있었다.&lt;/p&gt;
&lt;p data-end=&quot;6815&quot; data-start=&quot;6804&quot; data-ke-size=&quot;size16&quot;&gt;PC에서도 열어보고,&lt;/p&gt;
&lt;p data-end=&quot;6829&quot; data-start=&quot;6817&quot; data-ke-size=&quot;size16&quot;&gt;휴대폰에서도 열어봤다.&lt;/p&gt;
&lt;p data-end=&quot;6869&quot; data-start=&quot;6831&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터에서 Spring Boot를 실행하지 않아도 화면이 나왔다.&lt;/p&gt;
&lt;p data-end=&quot;6878&quot; data-start=&quot;6871&quot; data-ke-size=&quot;size16&quot;&gt;이때 처음으로&lt;/p&gt;
&lt;p data-end=&quot;6908&quot; data-start=&quot;6880&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Docker를 왜 사용하는지 조금 실감했다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;6969&quot; data-start=&quot;6910&quot; data-ke-size=&quot;size16&quot;&gt;Docker 자체를 공부할 때는 이미지, 컨테이너, 레이어 같은 용어부터 나오니까 꽤 추상적으로 느껴졌다.&lt;/p&gt;
&lt;p data-end=&quot;6974&quot; data-start=&quot;6971&quot; data-ke-size=&quot;size16&quot;&gt;그런데&lt;/p&gt;
&lt;blockquote data-end=&quot;7024&quot; data-start=&quot;6976&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;7024&quot; data-start=&quot;6978&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터가 아닌 곳에서 내가 만든 Spring Boot 프로젝트를 실행해야 한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;7063&quot; data-start=&quot;7026&quot; data-ke-size=&quot;size16&quot;&gt;라는 문제가 먼저 생기고 나니 Docker가 훨씬 이해하기 쉬웠다.&lt;/p&gt;
&lt;hr data-end=&quot;7068&quot; data-start=&quot;7065&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;7107&quot; data-start=&quot;7070&quot;&gt;Spring Boot Docker 배포하면서 확인하면 좋은 순서&lt;/h1&gt;
&lt;p data-end=&quot;7135&quot; data-start=&quot;7109&quot; data-ke-size=&quot;size16&quot;&gt;다시 한다면 나는 아래 순서로 확인할 것 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1. Spring Boot가 로컬에서 실행되는가?
        &amp;darr;
2. Gradle build가 성공하는가?
        &amp;darr;
3. jar가 정상 생성되는가?
        &amp;darr;
4. Java 버전이 맞는가?
        &amp;darr;
5. Docker build가 되는가?
        &amp;darr;
6. Docker run으로 로컬 실행되는가?
        &amp;darr;
7. PORT 설정이 배포 환경에 맞는가?
        &amp;darr;
8. 환경변수가 빠진 건 없는가?
        &amp;darr;
9. GitHub push
        &amp;darr;
10. Railway Build Log 확인
        &amp;darr;
11. Runtime Log 확인
        &amp;darr;
12. 외부 URL 접속&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;7547&quot; data-start=&quot;7511&quot; data-ke-size=&quot;size16&quot;&gt;이 순서대로 보면 문제가 생겼을 때 범위를 상당히 줄일 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;7598&quot; data-start=&quot;7549&quot; data-ke-size=&quot;size16&quot;&gt;Docker build부터 안 되는데 Railway 설정을 계속 보고 있을 필요가 없고,&lt;/p&gt;
&lt;p data-end=&quot;7666&quot; data-start=&quot;7600&quot; data-ke-size=&quot;size16&quot;&gt;Docker에서는 잘 되는데 배포에서만 안 된다면 환경변수나 포트처럼 &lt;b&gt;배포 환경의 차이&lt;/b&gt;를 먼저 의심할 수 있다.&lt;/p&gt;
&lt;hr data-end=&quot;7671&quot; data-start=&quot;7668&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;7689&quot; data-start=&quot;7673&quot;&gt;최소 구성만 다시 정리하면&lt;/h1&gt;
&lt;h3 data-end=&quot;7707&quot; data-start=&quot;7691&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Dockerfile&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;FROM eclipse-temurin:17-jdk

WORKDIR /app

COPY build/libs/*.jar app.jar

EXPOSE 8080

ENTRYPOINT [&quot;java&quot;, &quot;-jar&quot;, &quot;app.jar&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;7882&quot; data-start=&quot;7854&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;application.properties&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;server.port=${PORT:8080}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;7947&quot; data-start=&quot;7928&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;.dockerignore&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;.git
.gradle
.idea
*.log
.env&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;7998&quot; data-start=&quot;7992&quot; data-ke-size=&quot;size23&quot;&gt;빌드&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;excel&quot;&gt;&lt;code&gt;./gradlew clean bootJar&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;8054&quot; data-start=&quot;8037&quot; data-ke-size=&quot;size23&quot;&gt;Docker 이미지 생성&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;docker build -t my-spring-app .&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;8107&quot; data-start=&quot;8101&quot; data-ke-size=&quot;size23&quot;&gt;실행&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;docker run -p 8080:8080 my-spring-app&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;8163&quot; data-start=&quot;8160&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;8191&quot; data-start=&quot;8165&quot;&gt;직접 해보니 Docker보다 더 중요했던 것&lt;/h1&gt;
&lt;p data-end=&quot;8230&quot; data-start=&quot;8193&quot; data-ke-size=&quot;size16&quot;&gt;배포하기 전에는 Docker가 가장 어려운 부분일 거라고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;8266&quot; data-start=&quot;8232&quot; data-ke-size=&quot;size16&quot;&gt;막상 해보니 Dockerfile 자체는 생각보다 길지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;8299&quot; data-start=&quot;8268&quot; data-ke-size=&quot;size16&quot;&gt;오히려 계속 문제를 만들었던 건 &lt;b&gt;환경의 차이&lt;/b&gt;였다.&lt;/p&gt;
&lt;p data-end=&quot;8326&quot; data-start=&quot;8301&quot; data-ke-size=&quot;size16&quot;&gt;Windows와 Linux의 줄바꿈이 달랐고,&lt;/p&gt;
&lt;p data-end=&quot;8348&quot; data-start=&quot;8328&quot; data-ke-size=&quot;size16&quot;&gt;로컬과 Docker의 포트가 달랐고,&lt;/p&gt;
&lt;p data-end=&quot;8378&quot; data-start=&quot;8350&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터에는 당연히 있던 환경이 서버에는 없었다.&lt;/p&gt;
&lt;p data-end=&quot;8393&quot; data-start=&quot;8380&quot; data-ke-size=&quot;size16&quot;&gt;결국 배포라는 건 단순히&lt;/p&gt;
&lt;blockquote data-end=&quot;8411&quot; data-start=&quot;8395&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;8411&quot; data-start=&quot;8397&quot; data-ke-size=&quot;size16&quot;&gt;코드를 서버에 복사하는 것&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;8416&quot; data-start=&quot;8413&quot; data-ke-size=&quot;size16&quot;&gt;보다는&lt;/p&gt;
&lt;p data-end=&quot;8461&quot; data-start=&quot;8418&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;내 컴퓨터가 없어도 이 프로그램이 실행될 수 있는 환경을 만드는 것&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;8470&quot; data-start=&quot;8463&quot; data-ke-size=&quot;size16&quot;&gt;에 가까웠다.&lt;/p&gt;
&lt;p data-end=&quot;8499&quot; data-start=&quot;8472&quot; data-ke-size=&quot;size16&quot;&gt;Docker를 직접 사용하고 나서야 예전에 들었던&lt;/p&gt;
&lt;blockquote data-end=&quot;8517&quot; data-start=&quot;8501&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;8517&quot; data-start=&quot;8503&quot; data-ke-size=&quot;size16&quot;&gt;내 컴퓨터에서는 되는데요?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;8554&quot; data-start=&quot;8519&quot; data-ke-size=&quot;size16&quot;&gt;라는 말이 왜 개발자 농담처럼 쓰이는지 조금 더 이해하게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;8579&quot; data-start=&quot;8556&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 정말 내 컴퓨터가 아니어도 됐다.&lt;/p&gt;
&lt;hr data-end=&quot;8584&quot; data-start=&quot;8581&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;8596&quot; data-start=&quot;8586&quot; data-ke-size=&quot;size23&quot;&gt;한 줄 정리&lt;/h3&gt;
&lt;p data-end=&quot;8737&quot; data-start=&quot;8598&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Spring Boot Docker 배포에서 가장 먼저 확인할 것은 Docker보다 로컬 빌드 &amp;rarr; jar &amp;rarr; Docker 실행 &amp;rarr; 포트/환경변수 &amp;rarr; 실제 배포 순서다. 하나씩 분리해서 확인하면 어디에서 문제가 생겼는지 찾기가 훨씬 쉬워진다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>개발 노트</category>
      <category>docker</category>
      <category>Dockerfile</category>
      <category>gradle</category>
      <category>java 17</category>
      <category>railway</category>
      <category>spring boot</category>
      <category>Spring Boot Docker</category>
      <category>spring boot 배포</category>
      <category>WSL</category>
      <category>개발노트</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/24</guid>
      <comments>https://nocklock.tistory.com/24#entry24comment</comments>
      <pubDate>Sun, 20 Sep 2026 00:54:44 +0900</pubDate>
    </item>
    <item>
      <title>Git status에서 모든 파일이 modified로 뜰 때 &amp;mdash; WSL에서 만난 CRLF/LF 문제</title>
      <link>https://nocklock.tistory.com/23</link>
      <description>&lt;p data-end=&quot;123&quot; data-start=&quot;75&quot; data-ke-size=&quot;size16&quot;&gt;배포를 준비하면서 Windows에서 작업하던 프로젝트를 WSL Ubuntu에서 열었다.&lt;/p&gt;
&lt;p data-end=&quot;163&quot; data-start=&quot;125&quot; data-ke-size=&quot;size16&quot;&gt;평소처럼 프로젝트 폴더로 이동하고 git status를 입력했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오전 12_48_12.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l7inf/dJMcadXUz03/1UGUHgOh1J1qCK0XWbv1uk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l7inf/dJMcadXUz03/1UGUHgOh1J1qCK0XWbv1uk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l7inf/dJMcadXUz03/1UGUHgOh1J1qCK0XWbv1uk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl7inf%2FdJMcadXUz03%2F1UGUHgOh1J1qCK0XWbv1uk%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; alt=&quot;modified&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 20일 오전 12_48_12.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;208&quot; data-start=&quot;189&quot; data-ke-size=&quot;size16&quot;&gt;그런데 결과를 보고 순간 당황했다.&lt;/p&gt;
&lt;p data-end=&quot;253&quot; data-start=&quot;210&quot; data-ke-size=&quot;size16&quot;&gt;내가 수정한 기억이 없는 파일들이 전부 modified로 표시되고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;311&quot; data-start=&quot;255&quot; data-ke-size=&quot;size16&quot;&gt;Java 파일부터 Gradle 설정 파일, 문서 파일까지 거의 프로젝트 전체가 수정된 것처럼 보였다.&lt;/p&gt;
&lt;p data-end=&quot;327&quot; data-start=&quot;313&quot; data-ke-size=&quot;size16&quot;&gt;처음 든 생각은 단순했다.&lt;/p&gt;
&lt;p data-end=&quot;356&quot; data-start=&quot;329&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배포 준비하다가 프로젝트를 잘못 건드렸나?&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;361&quot; data-start=&quot;358&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;390&quot; data-start=&quot;363&quot; data-ke-size=&quot;size26&quot;&gt;내가 수정한 파일이 이렇게 많을 리가 없었다&lt;/h2&gt;
&lt;p data-end=&quot;426&quot; data-start=&quot;392&quot; data-ke-size=&quot;size16&quot;&gt;당시 내가 실제로 추가한 건 배포를 위한 설정 몇 개뿐이었다.&lt;/p&gt;
&lt;p data-end=&quot;464&quot; data-start=&quot;428&quot; data-ke-size=&quot;size16&quot;&gt;그런데 Git에서는 이런 식으로 수많은 파일이 변경됐다고 나왔다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;modified:   build.gradle
modified:   settings.gradle
modified:   src/main/java/...
modified:   docs/...
...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;599&quot; data-start=&quot;587&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 꽤 식겁했다.&lt;/p&gt;
&lt;p data-end=&quot;633&quot; data-start=&quot;601&quot; data-ke-size=&quot;size16&quot;&gt;이미 개발은 거의 끝난 상태였고 배포만 남겨둔 상황이었다.&lt;/p&gt;
&lt;p data-end=&quot;680&quot; data-start=&quot;635&quot; data-ke-size=&quot;size16&quot;&gt;여기서 파일 수십 개가 실제로 변경된 거라면 다시 확인해야 할 범위가 너무 컸다.&lt;/p&gt;
&lt;p data-end=&quot;725&quot; data-start=&quot;682&quot; data-ke-size=&quot;size16&quot;&gt;그래서 일단 코드를 되돌리기 전에 정말 내용이 바뀐 건지부터 확인하기로 했다.&lt;/p&gt;
&lt;hr data-end=&quot;730&quot; data-start=&quot;727&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;753&quot; data-start=&quot;732&quot; data-ke-size=&quot;size26&quot;&gt;실제 변경 내용을 다시 확인해봤다&lt;/h2&gt;
&lt;p data-end=&quot;793&quot; data-start=&quot;755&quot; data-ke-size=&quot;size16&quot;&gt;Git에는 줄바꿈 차이를 무시하고 변경 내용을 확인하는 옵션이 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;git diff --ignore-space-at-eol --stat&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;864&quot; data-start=&quot;846&quot; data-ke-size=&quot;size16&quot;&gt;실행해보니 결과가 완전히 달랐다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;lsl&quot;&gt;&lt;code&gt;.dockerignore | 7 +++++++
railway.toml  | 6 ++++++
2 files changed, 13 insertions(+)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;989&quot; data-start=&quot;964&quot; data-ke-size=&quot;size16&quot;&gt;실제로 내가 수정한 파일은 거의 이것뿐이었다.&lt;/p&gt;
&lt;p data-end=&quot;1000&quot; data-start=&quot;991&quot; data-ke-size=&quot;size16&quot;&gt;그제야 안심했다.&lt;/p&gt;
&lt;p data-end=&quot;1051&quot; data-start=&quot;1002&quot; data-ke-size=&quot;size16&quot;&gt;그리고 원인을 찾아보니 Windows와 Linux의 &lt;b&gt;줄바꿈 방식 차이&lt;/b&gt; 때문이었다.&lt;/p&gt;
&lt;hr data-end=&quot;1056&quot; data-start=&quot;1053&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1087&quot; data-start=&quot;1058&quot; data-ke-size=&quot;size26&quot;&gt;CRLF와 LF가 뭐길래 파일 전체가 바뀐 걸까&lt;/h2&gt;
&lt;p data-end=&quot;1126&quot; data-start=&quot;1089&quot; data-ke-size=&quot;size16&quot;&gt;Windows와 Linux는 줄바꿈을 표현하는 방식이 조금 다르다.&lt;/p&gt;
&lt;p data-end=&quot;1144&quot; data-start=&quot;1128&quot; data-ke-size=&quot;size16&quot;&gt;Windows에서는 일반적으로&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;CRLF&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1172&quot; data-start=&quot;1164&quot; data-ke-size=&quot;size16&quot;&gt;Linux에서는&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;LF&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1197&quot; data-start=&quot;1190&quot; data-ke-size=&quot;size16&quot;&gt;를 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;1238&quot; data-start=&quot;1199&quot; data-ke-size=&quot;size16&quot;&gt;개발자가 코드를 볼 때는 둘 다 그냥 다음 줄로 넘어간 것처럼 보인다.&lt;/p&gt;
&lt;p data-end=&quot;1262&quot; data-start=&quot;1240&quot; data-ke-size=&quot;size16&quot;&gt;그래서 평소에는 거의 신경 쓰지 않는다.&lt;/p&gt;
&lt;p data-end=&quot;1287&quot; data-start=&quot;1264&quot; data-ke-size=&quot;size16&quot;&gt;그런데 Git 입장에서는 이야기가 다르다.&lt;/p&gt;
&lt;p data-end=&quot;1331&quot; data-start=&quot;1289&quot; data-ke-size=&quot;size16&quot;&gt;줄 끝에 들어가는 문자가 달라지면 Git은 그것도 변경으로 판단할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1384&quot; data-start=&quot;1333&quot; data-ke-size=&quot;size16&quot;&gt;내 프로젝트는 Windows에서 작업하던 프로젝트였고, 그걸 WSL Ubuntu에서 열었다.&lt;/p&gt;
&lt;p data-end=&quot;1463&quot; data-start=&quot;1386&quot; data-ke-size=&quot;size16&quot;&gt;환경이 Windows에서 Linux로 바뀌면서 줄바꿈이 다르게 인식됐고, 결과적으로 Git에서는 파일 전체가 수정된 것처럼 보였던 것이다.&lt;/p&gt;
&lt;hr data-end=&quot;1468&quot; data-start=&quot;1465&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1499&quot; data-start=&quot;1470&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;git status만 보고 바로 되돌렸다면?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-end=&quot;1517&quot; data-start=&quot;1501&quot; data-ke-size=&quot;size16&quot;&gt;이때 조금 위험했던 게 있다.&lt;/p&gt;
&lt;p data-end=&quot;1535&quot; data-start=&quot;1519&quot; data-ke-size=&quot;size16&quot;&gt;git status만 보고&lt;/p&gt;
&lt;blockquote data-end=&quot;1560&quot; data-start=&quot;1537&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1560&quot; data-start=&quot;1539&quot; data-ke-size=&quot;size16&quot;&gt;이상하게 바뀌었네. 전부 되돌려야겠다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1603&quot; data-start=&quot;1562&quot; data-ke-size=&quot;size16&quot;&gt;라고 생각했다면 내가 실제로 추가한 배포 설정까지 같이 날릴 수도 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1623&quot; data-start=&quot;1605&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이번에 느낀 건 간단했다.&lt;/p&gt;
&lt;p data-end=&quot;1669&quot; data-start=&quot;1625&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Git에서 예상하지 못한 변경이 보이면 일단 내용을 확인하는 게 먼저다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1693&quot; data-start=&quot;1671&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 이런 명령어들이 도움이 된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;git diff&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1737&quot; data-start=&quot;1717&quot; data-ke-size=&quot;size16&quot;&gt;파일별 변경 내용을 확인할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1758&quot; data-start=&quot;1739&quot; data-ke-size=&quot;size16&quot;&gt;줄바꿈 때문에 보기 어려운 경우에는&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;git diff --ignore-space-at-eol&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1832&quot; data-start=&quot;1804&quot; data-ke-size=&quot;size16&quot;&gt;처럼 줄 끝의 공백 차이를 무시하고 볼 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;1862&quot; data-start=&quot;1834&quot; data-ke-size=&quot;size16&quot;&gt;전체 변경 규모만 보고 싶다면 내가 사용했던 것처럼&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;git diff --ignore-space-at-eol --stat&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1924&quot; data-start=&quot;1915&quot; data-ke-size=&quot;size16&quot;&gt;도 꽤 유용했다.&lt;/p&gt;
&lt;p data-end=&quot;1940&quot; data-start=&quot;1926&quot; data-ke-size=&quot;size16&quot;&gt;나는 이걸 실행하고 나서야&lt;/p&gt;
&lt;p data-end=&quot;1968&quot; data-start=&quot;1942&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;아, 코드가 전부 바뀐 게 아니구나.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1985&quot; data-start=&quot;1970&quot; data-ke-size=&quot;size16&quot;&gt;라는 걸 확인할 수 있었다.&lt;/p&gt;
&lt;hr data-end=&quot;1990&quot; data-start=&quot;1987&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2030&quot; data-start=&quot;1992&quot; data-ke-size=&quot;size26&quot;&gt;Windows와 WSL을 같이 쓰면 한 번쯤 만날 수 있는 문제&lt;/h2&gt;
&lt;p data-end=&quot;2064&quot; data-start=&quot;2032&quot; data-ke-size=&quot;size16&quot;&gt;나는 Windows에서 IntelliJ로 개발하고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;2113&quot; data-start=&quot;2066&quot; data-ke-size=&quot;size16&quot;&gt;그러다가 Docker와 배포 환경을 준비하면서 WSL Ubuntu까지 사용하게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;2168&quot; data-start=&quot;2115&quot; data-ke-size=&quot;size16&quot;&gt;같은 프로젝트인데도 어느 환경에서 파일을 열고 저장하느냐에 따라 줄바꿈 문제가 생길 수 있었다.&lt;/p&gt;
&lt;p data-end=&quot;2195&quot; data-start=&quot;2170&quot; data-ke-size=&quot;size16&quot;&gt;특히 이런 상황이라면 한 번 의심해볼 만하다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;Windows에서 개발하던 프로젝트를 WSL에서 열었다.
&amp;darr;
코드는 거의 건드리지 않았다.
&amp;darr;
git status를 실행했다.
&amp;darr;
갑자기 수십 개 파일이 modified로 표시된다.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2362&quot; data-start=&quot;2312&quot; data-ke-size=&quot;size16&quot;&gt;이 상황이라면 진짜 코드가 바뀐 건지 확인하기 전에 CRLF/LF 문제부터 보는 게 좋다.&lt;/p&gt;
&lt;hr data-end=&quot;2367&quot; data-start=&quot;2364&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2384&quot; data-start=&quot;2369&quot; data-ke-size=&quot;size26&quot;&gt;그럼 어떻게 예방할까?&lt;/h2&gt;
&lt;p data-end=&quot;2426&quot; data-start=&quot;2386&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트에서 줄바꿈 규칙을 명확하게 정해두면 이런 문제를 줄일 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2461&quot; data-start=&quot;2428&quot; data-ke-size=&quot;size16&quot;&gt;대표적으로 .gitattributes를 사용할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2476&quot; data-start=&quot;2463&quot; data-ke-size=&quot;size16&quot;&gt;예를 들면 이런 식이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;* text=auto&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2532&quot; data-start=&quot;2503&quot; data-ke-size=&quot;size16&quot;&gt;조금 더 명확하게 LF를 사용하도록 정할 수도 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;* text=auto eol=lf&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2627&quot; data-start=&quot;2566&quot; data-ke-size=&quot;size16&quot;&gt;다만 이미 여러 사람이 작업하는 프로젝트라면 갑자기 줄바꿈 규칙을 바꾸기 전에 기존 설정을 확인하는 게 좋다.&lt;/p&gt;
&lt;p data-end=&quot;2668&quot; data-start=&quot;2629&quot; data-ke-size=&quot;size16&quot;&gt;설정 하나 바꿨다가 정말로 파일 전체가 변경되는 경우도 있기 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;2704&quot; data-start=&quot;2670&quot; data-ke-size=&quot;size16&quot;&gt;Git의 core.autocrlf 설정도 확인할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;git config --get core.autocrlf&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2794&quot; data-start=&quot;2750&quot; data-ke-size=&quot;size16&quot;&gt;Windows와 Linux를 같이 사용하는 환경이라면 한 번쯤 확인해둘 만하다.&lt;/p&gt;
&lt;hr data-end=&quot;2799&quot; data-start=&quot;2796&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2822&quot; data-start=&quot;2801&quot; data-ke-size=&quot;size26&quot;&gt;이번에는 아무것도 망가지지 않았다&lt;/h2&gt;
&lt;p data-end=&quot;2880&quot; data-start=&quot;2824&quot; data-ke-size=&quot;size16&quot;&gt;배포하려고 Linux 환경으로 넘어갔다가 갑자기 프로젝트 전체가 수정된 것처럼 보여서 잠깐 긴장했다.&lt;/p&gt;
&lt;p data-end=&quot;2906&quot; data-start=&quot;2882&quot; data-ke-size=&quot;size16&quot;&gt;결론적으로 실제 코드는 거의 바뀌지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;2937&quot; data-start=&quot;2908&quot; data-ke-size=&quot;size16&quot;&gt;문제는 Windows와 Linux의 줄바꿈 차이였다.&lt;/p&gt;
&lt;p data-end=&quot;2981&quot; data-start=&quot;2939&quot; data-ke-size=&quot;size16&quot;&gt;이번 일을 겪고 나서 git status 결과를 조금 다르게 보게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;3031&quot; data-start=&quot;2983&quot; data-ke-size=&quot;size16&quot;&gt;modified라고 적혀 있다고 해서 무조건 내가 코드를 수정했다는 뜻은 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;3038&quot; data-start=&quot;3033&quot; data-ke-size=&quot;size16&quot;&gt;중요한 건&lt;/p&gt;
&lt;p data-end=&quot;3061&quot; data-start=&quot;3040&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;무엇이 달라졌는지 확인하는 것.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3112&quot; data-start=&quot;3063&quot; data-ke-size=&quot;size16&quot;&gt;앞으로 또 프로젝트 전체가 갑자기 빨간색으로 변해 있더라도 이번보다는 덜 놀랄 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;3118&quot; data-start=&quot;3114&quot; data-ke-size=&quot;size16&quot;&gt;아마도.&lt;/p&gt;
&lt;hr data-end=&quot;3123&quot; data-start=&quot;3120&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3140&quot; data-start=&quot;3125&quot; data-ke-size=&quot;size23&quot;&gt;이번에 사용한 명령어&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3178&quot; data-start=&quot;3166&quot; data-ke-size=&quot;size16&quot;&gt;현재 변경 파일 확인.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;git diff&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3214&quot; data-start=&quot;3202&quot; data-ke-size=&quot;size16&quot;&gt;실제 변경 내용 확인.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;git diff --ignore-space-at-eol --stat&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3292&quot; data-start=&quot;3267&quot; data-ke-size=&quot;size16&quot;&gt;줄 끝 차이를 무시하고 실제 변경 규모 확인.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;git config --get core.autocrlf&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3355&quot; data-start=&quot;3338&quot; data-ke-size=&quot;size16&quot;&gt;Git 줄바꿈 관련 설정 확인.&lt;/p&gt;
&lt;hr data-end=&quot;3360&quot; data-start=&quot;3357&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;3372&quot; data-start=&quot;3362&quot; data-ke-size=&quot;size23&quot;&gt;한 줄 정리&lt;/h3&gt;
&lt;p data-end=&quot;3467&quot; data-start=&quot;3374&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Windows 프로젝트를 WSL에서 열었는데 Git에서 모든 파일이 modified로 나온다면, 코드를 되돌리기 전에 CRLF/LF 줄바꿈 차이부터 확인해보자.&lt;/b&gt;&lt;/p&gt;</description>
      <category>개발 노트</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/23</guid>
      <comments>https://nocklock.tistory.com/23#entry23comment</comments>
      <pubDate>Sun, 20 Sep 2026 00:48:33 +0900</pubDate>
    </item>
    <item>
      <title>RE:개발자 &amp;mdash; 다시 개발자가 되어가는 기록 | 전체 목차</title>
      <link>https://nocklock.tistory.com/22</link>
      <description>&lt;p data-end=&quot;1507&quot; data-start=&quot;1452&quot; data-ke-size=&quot;size16&quot;&gt;개발자로 일했지만, 어느 순간 내가 매일 사용하던 기술조차 제대로 설명하지 못한다는 생각이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;1524&quot; data-start=&quot;1512&quot; data-ke-size=&quot;size16&quot;&gt;그래서 다시 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;1580&quot; data-start=&quot;1529&quot; data-ke-size=&quot;size16&quot;&gt;Java부터 Git, Gradle, Spring Boot, API, OCR, 프론트엔드까지.&lt;/p&gt;
&lt;p data-end=&quot;1640&quot; data-start=&quot;1585&quot; data-ke-size=&quot;size16&quot;&gt;무언가를 새로 배우는 기록이라기보다, 알고 있다고 생각했던 것들을 다시 이해해 가는 기록에 가깝다.&lt;/p&gt;
&lt;p data-end=&quot;1693&quot; data-start=&quot;1645&quot; data-ke-size=&quot;size16&quot;&gt;그리고 지금은 AI와 함께 하나의 서비스를 직접 만들어보면서 그 과정을 기록하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;1728&quot; data-start=&quot;1698&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1728&quot; data-start=&quot;1698&quot; data-ke-size=&quot;size16&quot;&gt;이 페이지는 &lt;b&gt;RE:개발자 시리즈의 전체 목차&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;code_1789986818485&quot; data-ke-type=&quot;html&quot; data-source=&quot;&amp;lt;div id=&amp;quot;redev-auto-toc&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&quot;&gt;
&lt;div id=&quot;redev-auto-toc&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;</description>
      <category>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/22</guid>
      <comments>https://nocklock.tistory.com/22#entry22comment</comments>
      <pubDate>Sun, 20 Sep 2026 00:29:10 +0900</pubDate>
    </item>
    <item>
      <title>AI를 붙이면 끝일 줄 알았다, 실제 테스트는 달랐다 | RE:개발자 #8</title>
      <link>https://nocklock.tistory.com/12</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;프론트엔드를 붙이고 나니 기분이 꽤 좋았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사진을 선택하고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;분석 버튼을 누르면,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Spring Boot API가 호출되고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;분석 결과가 화면에 나타났다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;백엔드에서 JSON으로만 확인하던 기능이 실제 화면에서 동작했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 서비스를 직접 사용해보면서 생각이 달라졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;기능이 동작하는 것과 서비스가 제대로 동작하는 것은 달랐다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;프론트엔드는 단순히 화면을 예쁘게 보여주는 역할만 하는 것이 아니었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;오히려 지금까지 숨어 있던 문제를 찾아주는 테스트 도구에 가까웠다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 17일 오전 10_20_22.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QVZag/dJMcagG9aoK/ENPQSQkmleCOdSrX2GkXm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QVZag/dJMcagG9aoK/ENPQSQkmleCOdSrX2GkXm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QVZag/dJMcagG9aoK/ENPQSQkmleCOdSrX2GkXm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQVZag%2FdJMcagG9aoK%2FENPQSQkmleCOdSrX2GkXm0%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; alt=&quot;오류이미지&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 17일 오전 10_20_22.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;API 테스트에서는 문제가 없어 보였다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;백엔드를 개발할 때는 주로 API의 응답을 확인했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 분석 요청을 보내면 이런 결과가 내려왔다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;riskScore&quot;: 82,
  &quot;riskLevel&quot;: &quot;CRITICAL&quot;,
  &quot;detectedItems&quot;: [
    {
      &quot;type&quot;: &quot;PHONE_NUMBER&quot;,
      &quot;value&quot;: &quot;010-****-5678&quot;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;응답도 정상이고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;상태 코드도 정상이고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;원하는 데이터도 들어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그러면 자연스럽게 생각하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;잘 되고 있네.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 실제 화면에 이 데이터를 뿌려보니 질문이 하나씩 생기기 시작했다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;첫 번째 문제&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&quot;개인정보가 발견된 건 알겠는데 어디에 있는 거지?&quot;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;화면에는 이런 결과가 표시됐다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&gt;위험도 : HIGH

탐지된 개인정보
- 전화번호
- 이메일
- 이름&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개발자인 나는 이 결과를 이해할 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 사용자의 입장에서 보면 부족했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사진에 전화번호가 있다고 알려주기는 하지만,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;사진의 어느 부분에 전화번호가 있는지는 알 수 없었다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 사진 한 장에 간판, 명함, 노트북 화면, 문서가 함께 찍혀 있다면 사용자는 결국 사진 전체를 다시 확인해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그 순간 서비스의 핵심 기능을 다시 생각하게 됐다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;내가 만들고 싶은 것은 단순히&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&quot;개인정보가 있습니다.&quot;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;라고 알려주는 프로그램이 아니었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;궁극적으로는&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&quot;여기에 개인정보가 있으니 이 부분을 확인하세요.&quot;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;라고 알려줘야 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 OCR 결과에서 텍스트만 가져오는 것으로 끝내지 않고 &lt;/span&gt;&lt;b&gt;&lt;span&gt;텍스트의 위치 정보까지 활용해야 한다는 결론&lt;/span&gt;&lt;/b&gt;&lt;span&gt;을 내렸다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;OCR 결과에는 이미 답이 있었다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;OCR은 단순히 글자만 반환하는 것이 아니었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;텍스트가 이미지의 어디에 존재하는지 좌표 정보도 가지고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개념적으로 보면 이런 형태다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;&quot;010-1234-5678&quot;

x : 420
y : 310
width : 230
height : 45&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그렇다면 해야 할 일은 명확했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;OCR
 &amp;darr;
텍스트 + 좌표 추출
 &amp;darr;
개인정보 탐지
 &amp;darr;
탐지된 개인정보와 OCR 텍스트 연결
 &amp;darr;
BoundingBox 생성&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;백엔드에 이미 존재하던 두 기능을 연결하면 됐다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하나는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;OCR&lt;/span&gt;&lt;/b&gt;&lt;span&gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다른 하나는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;PII 탐지&lt;/span&gt;&lt;/b&gt;&lt;span&gt;였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;문제는 이 둘이 각각 따로 움직이고 있었다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;기능이 존재한다고 연결되어 있는 것은 아니었다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 부분이 이번 개발에서 꽤 재미있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;OCR은 정상적으로 동작했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;PII 탐지도 정상적으로 동작했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;둘 다 개별적으로 보면 문제가 없었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 서비스 입장에서는 둘 사이에 연결이 없었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 OCR이&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;010-1234-5678&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이라는 문자열과 위치를 찾아냈고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;PII 분석기가&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;PHONE_NUMBER&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;라고 판단했다고 해도,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 구조에서는&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 전화번호가 OCR 결과의 어느 위치에서 발견된 것인가?&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;를 알 수 없었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 데이터 구조를 다시 바라보기 시작했다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;BoundingBox를 추가했다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결국 탐지 결과에 위치 정보를 함께 전달하도록 구조를 확장했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개념적으로는 이런 형태다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;type&quot;: &quot;PHONE_NUMBER&quot;,
  &quot;value&quot;: &quot;010-****-5678&quot;,
  &quot;confidence&quot;: 0.99,
  &quot;boundingBox&quot;: {
    &quot;x&quot;: 420,
    &quot;y&quot;: 310,
    &quot;width&quot;: 230,
    &quot;height&quot;: 45
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 데이터가 있으면 프론트엔드에서 할 수 있는 일이 크게 늘어난다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사진 위에 빨간 사각형을 그릴 수도 있고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;위험 영역을 강조할 수도 있고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;나중에는 해당 영역만 자동으로 블러 처리하는 기능도 만들 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;단순히 데이터 하나를 추가한 것이지만,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;서비스의 방향이 훨씬 명확해졌다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;두 번째 문제&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;실제 데이터는 내가 예상한 것처럼 깔끔하지 않았다&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개발할 때 가장 편한 데이터는 내가 예상한 데이터다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;전화번호 &amp;rarr; 전화번호답게 들어온다.
이메일 &amp;rarr; 이메일답게 들어온다.
주소 &amp;rarr; 주소답게 들어온다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 실제 이미지는 그렇지 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;OCR은 사진의 해상도나 각도,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;글자의 크기,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;배경,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;빛,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;글자 간격 등에 따라 결과가 달라질 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 사람이 보기에는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;010-1234-5678&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;인데 OCR 결과에서는 일부 문자가 잘못 인식될 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 개인정보 탐지 로직에서는 문자열이 달라지면 탐지 결과까지 달라질 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그때 다시 느꼈다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;테스트용 데이터에서 잘 되는 것과 실제 사진에서 잘 되는 것은 완전히 다른 문제였다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 직접 여러 형태의 이미지를 넣어보면서 결과를 확인하기 시작했다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;세 번째 문제&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;결과가 없을 때도 화면은 정상적이어야 했다&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개발자는 성공한 경우를 먼저 만든다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;나 역시 처음에는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;사진 업로드
&amp;rarr; 분석 성공
&amp;rarr; 개인정보 탐지
&amp;rarr; 결과 출력&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이라는 정상 흐름을 먼저 생각했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 실제 사용자는 항상 정상적인 사진만 올리지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개인정보가 없는 사진도 있고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;메타데이터가 없는 이미지도 있고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;지원하지 않는 파일을 선택할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;분석 중 오류가 발생할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 화면에도 각각의 상태가 필요했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;분석 전

&amp;darr;

분석 중

&amp;darr;

분석 성공

또는

&amp;darr;

탐지 결과 없음

또는

&amp;darr;

분석 실패&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 상태를 구분하지 않으면 사용자는 버튼을 눌렀는데 분석 중인지,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;오류가 난 것인지,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정말 아무것도 발견되지 않은 것인지 알 수 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;작은 차이지만 사용성에서는 꽤 큰 차이였다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;프론트엔드가 백엔드를 다시 설계하게 만들었다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처음에는 이렇게 생각했다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;백엔드 기능은 거의 끝났으니 이제 화면만 붙이면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 실제로는 반대였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;화면을 만들고 직접 서비스를 사용해보니 백엔드에서 부족한 데이터가 보였고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;API 구조를 다시 보게 됐고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예외 상황도 생각하게 됐다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결국 이런 흐름이 반복됐다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;백엔드 구현
   &amp;darr;
프론트엔드 연결
   &amp;darr;
직접 사용
   &amp;darr;
문제 발견
   &amp;darr;
백엔드 수정
   &amp;darr;
다시 프론트엔드 테스트&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예전에는 이것을 번거로운 수정 작업이라고 생각했을 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;지금은 조금 다르게 느껴진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;이 과정 자체가 서비스를 만드는 과정이었다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;AI도 문제 해결 과정에서 계속 사용했다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에도 ChatGPT와 Claude를 적극적으로 사용했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다만 단순히&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;코드를 만들어줘.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;라고 요청하는 방식보다는 문제를 함께 쪼개는 데 많이 사용했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;OCR에서는 좌표가 나오고 있는데
현재 개인정보 탐지 결과에는 좌표가 없다.

두 데이터를 어떤 기준으로 연결하는 것이 좋을까?&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;같이 현재 구조와 문제를 설명했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI가 제안한 방법을 그대로 사용하는 것이 아니라,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 DTO 구조와 기존 코드에 맞는지 확인하고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;필요한 부분만 가져와 적용했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;특히 익숙하지 않은 프론트엔드 영역에서는 브라우저에서 어떤 데이터를 어떻게 표현해야 하는지 빠르게 확인하는 데 도움이 됐다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결국 중요한 것은 질문이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;문제를 정확하게 설명할수록 AI가 주는 답도 훨씬 구체적이었다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;직접 써봐야 문제가 보인다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에 가장 크게 배운 것은 이것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;코드를 보고 있으면 기능이 보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;API를 테스트하면 데이터가 보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 &lt;/span&gt;&lt;b&gt;&lt;span&gt;화면에서 직접 사용해봐야 사용자의 문제가 보인다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;전화번호를 탐지하는 기능을 만드는 것과&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사용자에게 전화번호가 어디 있는지 알려주는 것은 다른 문제였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;분석 결과를 반환하는 것과&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사용자가 결과를 이해할 수 있게 만드는 것도 다른 문제였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;프론트엔드를 붙인 덕분에 오히려 백엔드의 부족한 부분을 발견할 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 하나씩 연결하면서 서비스의 모습도 조금 더 선명해지고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;지금의 목표는 단순하다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;사진을 올린다.

&amp;darr;

위험 요소를 찾는다.

&amp;darr;

어디가 위험한지 보여준다.

&amp;darr;

필요하다면 그 부분을 가린다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처음에는 이미지 분석 API 하나에서 시작했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 직접 사용해보고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;부족한 부분을 찾고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다시 고치다 보니 조금씩 내가 처음 생각했던 서비스에 가까워지고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;기능을 만드는 것도 중요하지만&lt;/span&gt;&lt;br /&gt;&lt;span&gt;직접 사용해보는 것이 더 중요할 때가 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에는 프론트엔드가 그 사실을 알려줬다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;</description>
      <category>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/12</guid>
      <comments>https://nocklock.tistory.com/12#entry12comment</comments>
      <pubDate>Sat, 19 Sep 2026 22:20:48 +0900</pubDate>
    </item>
    <item>
      <title>우리는 앱을 설치할 때, 우리를 조금씩 넘겨준다.</title>
      <link>https://nocklock.tistory.com/13</link>
      <description>&lt;h3 data-end=&quot;196&quot; data-start=&quot;160&quot; data-ke-size=&quot;size23&quot;&gt;사진, 위치, 연락처, 마이크&amp;hellip; &amp;lsquo;허용&amp;rsquo; 버튼 하나의 의미&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 17일 오전 10_30_04.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5OQnx/dJMcagAeAXN/ltYOPTrwlta0y5XkLm0rkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5OQnx/dJMcagAeAXN/ltYOPTrwlta0y5XkLm0rkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5OQnx/dJMcagAeAXN/ltYOPTrwlta0y5XkLm0rkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5OQnx%2FdJMcagAeAXN%2FltYOPTrwlta0y5XkLm0rkK%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;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 17일 오전 10_30_04.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;209&quot; data-start=&quot;198&quot; data-ke-size=&quot;size16&quot;&gt;앱을 하나 설치했다.&lt;/p&gt;
&lt;p data-end=&quot;248&quot; data-start=&quot;211&quot; data-ke-size=&quot;size16&quot;&gt;사진 접근을 허용했다.&lt;br /&gt;위치도 허용했다.&lt;br /&gt;마이크도 허용했다.&lt;/p&gt;
&lt;p data-end=&quot;260&quot; data-start=&quot;250&quot; data-ke-size=&quot;size16&quot;&gt;별 생각은 없었다.&lt;/p&gt;
&lt;p data-end=&quot;309&quot; data-start=&quot;262&quot; data-ke-size=&quot;size16&quot;&gt;필요하다고 하니까 눌렀고,&lt;br /&gt;안 누르면 기능이 제대로 안 될 것 같아서 또 눌렀다.&lt;/p&gt;
&lt;p data-end=&quot;332&quot; data-start=&quot;311&quot; data-ke-size=&quot;size16&quot;&gt;그런데 어느 순간 이런 생각이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;365&quot; data-start=&quot;334&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;나는 이 앱에게 대체 어디까지 나를 보여준 걸까.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;370&quot; data-start=&quot;367&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;394&quot; data-start=&quot;372&quot; data-ke-size=&quot;size26&quot;&gt;&amp;lsquo;허용&amp;rsquo;은 생각보다 가벼운 버튼이다&lt;/h2&gt;
&lt;p data-end=&quot;420&quot; data-start=&quot;396&quot; data-ke-size=&quot;size16&quot;&gt;새로운 앱을 설치하면 익숙한 화면이 나온다.&lt;/p&gt;
&lt;blockquote data-end=&quot;511&quot; data-start=&quot;422&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;511&quot; data-start=&quot;424&quot; data-ke-size=&quot;size16&quot;&gt;사진 접근을 허용하시겠습니까?&lt;br /&gt;위치 정보 사용을 허용하시겠습니까?&lt;br /&gt;마이크 접근을 허용하시겠습니까?&lt;br /&gt;연락처에 접근하도록 허용하시겠습니까?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;529&quot; data-start=&quot;513&quot; data-ke-size=&quot;size16&quot;&gt;우리는 대부분 빠르게 누른다.&lt;/p&gt;
&lt;p data-end=&quot;580&quot; data-start=&quot;531&quot; data-ke-size=&quot;size16&quot;&gt;앱을 설치한 목적은 권한을 읽는 것이 아니라&lt;br /&gt;그 앱을 빨리 사용하는 것이기 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;600&quot; data-start=&quot;582&quot; data-ke-size=&quot;size16&quot;&gt;카메라 앱이니 사진이 필요하겠지.&lt;/p&gt;
&lt;p data-end=&quot;619&quot; data-start=&quot;602&quot; data-ke-size=&quot;size16&quot;&gt;지도 앱이니 위치가 필요하겠지.&lt;/p&gt;
&lt;p data-end=&quot;639&quot; data-start=&quot;621&quot; data-ke-size=&quot;size16&quot;&gt;통화 앱이니 마이크가 필요하겠지.&lt;/p&gt;
&lt;p data-end=&quot;653&quot; data-start=&quot;641&quot; data-ke-size=&quot;size16&quot;&gt;여기까지는 자연스럽다.&lt;/p&gt;
&lt;p data-end=&quot;714&quot; data-start=&quot;655&quot; data-ke-size=&quot;size16&quot;&gt;문제는 어느 순간부터&lt;br /&gt;&lt;b&gt;&amp;ldquo;이 기능에 정말 이 권한이 필요한가?&amp;rdquo;&lt;/b&gt;를 잘 묻지 않게 된다는 것이다.&lt;/p&gt;
&lt;hr data-end=&quot;719&quot; data-start=&quot;716&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;746&quot; data-start=&quot;721&quot; data-ke-size=&quot;size26&quot;&gt;사진 하나도 단순한 사진이 아닐 수 있다&lt;/h2&gt;
&lt;p data-end=&quot;773&quot; data-start=&quot;748&quot; data-ke-size=&quot;size16&quot;&gt;예전에 나는 사진을 그냥 이미지라고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;805&quot; data-start=&quot;775&quot; data-ke-size=&quot;size16&quot;&gt;사람이 있고,&lt;br /&gt;풍경이 있고,&lt;br /&gt;음식이 있는 파일.&lt;/p&gt;
&lt;p data-end=&quot;844&quot; data-start=&quot;807&quot; data-ke-size=&quot;size16&quot;&gt;그런데 개발하면서 이미지 데이터를 직접 다뤄보니 조금 달라 보였다.&lt;/p&gt;
&lt;p data-end=&quot;881&quot; data-start=&quot;846&quot; data-ke-size=&quot;size16&quot;&gt;사진에는 우리가 보는 화면 외에도 여러 정보가 존재할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;890&quot; data-start=&quot;883&quot; data-ke-size=&quot;size16&quot;&gt;촬영한 시간,&lt;/p&gt;
&lt;p data-end=&quot;899&quot; data-start=&quot;892&quot; data-ke-size=&quot;size16&quot;&gt;사용한 기기,&lt;/p&gt;
&lt;p data-end=&quot;916&quot; data-start=&quot;901&quot; data-ke-size=&quot;size16&quot;&gt;경우에 따라 위치 정보까지.&lt;/p&gt;
&lt;p data-end=&quot;942&quot; data-start=&quot;918&quot; data-ke-size=&quot;size16&quot;&gt;그리고 사진 속 화면 자체에도 정보가 있다.&lt;/p&gt;
&lt;p data-end=&quot;970&quot; data-start=&quot;944&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 책상 사진 한 장을 찍었다고 해보자.&lt;/p&gt;
&lt;p data-end=&quot;985&quot; data-start=&quot;972&quot; data-ke-size=&quot;size16&quot;&gt;사진에는 노트북이 있고,&lt;/p&gt;
&lt;p data-end=&quot;1002&quot; data-start=&quot;987&quot; data-ke-size=&quot;size16&quot;&gt;그 옆에 택배 송장이 있고,&lt;/p&gt;
&lt;p data-end=&quot;1024&quot; data-start=&quot;1004&quot; data-ke-size=&quot;size16&quot;&gt;뒤쪽 모니터에는 이메일이 열려 있고,&lt;/p&gt;
&lt;p data-end=&quot;1047&quot; data-start=&quot;1026&quot; data-ke-size=&quot;size16&quot;&gt;벽에는 일정표가 붙어 있을 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;1067&quot; data-start=&quot;1049&quot; data-ke-size=&quot;size16&quot;&gt;사람에게는 평범한 일상 사진이다.&lt;/p&gt;
&lt;p data-end=&quot;1082&quot; data-start=&quot;1069&quot; data-ke-size=&quot;size16&quot;&gt;하지만 기술의 입장에서는&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;사진 속 문자
+
촬영 정보
+
위치
+
시간&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1145&quot; data-start=&quot;1123&quot; data-ke-size=&quot;size16&quot;&gt;처럼 여러 데이터의 조합이 될 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1165&quot; data-start=&quot;1147&quot; data-ke-size=&quot;size16&quot;&gt;하나씩 보면 별것 아닌 정보인데,&lt;/p&gt;
&lt;p data-end=&quot;1193&quot; data-start=&quot;1167&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;여러 정보가 합쳐지면 이야기가 달라진다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1198&quot; data-start=&quot;1195&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1226&quot; data-start=&quot;1200&quot; data-ke-size=&quot;size26&quot;&gt;위치 정보는 단순히 &amp;lsquo;현재 위치&amp;rsquo;가 아니다&lt;/h2&gt;
&lt;p data-end=&quot;1241&quot; data-start=&quot;1228&quot; data-ke-size=&quot;size16&quot;&gt;위치 권한도 마찬가지다.&lt;/p&gt;
&lt;p data-end=&quot;1282&quot; data-start=&quot;1243&quot; data-ke-size=&quot;size16&quot;&gt;서울에 있는 사람이라는 사실 하나만으로는 특별한 정보가 아닐 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1304&quot; data-start=&quot;1284&quot; data-ke-size=&quot;size16&quot;&gt;하지만 위치가 반복적으로 기록된다면?&lt;/p&gt;
&lt;p data-end=&quot;1325&quot; data-start=&quot;1306&quot; data-ke-size=&quot;size16&quot;&gt;아침 8시에 출발하는 장소가 있고,&lt;/p&gt;
&lt;p data-end=&quot;1343&quot; data-start=&quot;1327&quot; data-ke-size=&quot;size16&quot;&gt;9시에 도착하는 장소가 있고,&lt;/p&gt;
&lt;p data-end=&quot;1365&quot; data-start=&quot;1345&quot; data-ke-size=&quot;size16&quot;&gt;저녁마다 다시 돌아오는 장소가 있다.&lt;/p&gt;
&lt;p data-end=&quot;1384&quot; data-start=&quot;1367&quot; data-ke-size=&quot;size16&quot;&gt;주말마다 방문하는 장소도 있다.&lt;/p&gt;
&lt;p data-end=&quot;1400&quot; data-start=&quot;1386&quot; data-ke-size=&quot;size16&quot;&gt;그 데이터가 충분히 쌓이면&lt;/p&gt;
&lt;p data-end=&quot;1404&quot; data-start=&quot;1402&quot; data-ke-size=&quot;size16&quot;&gt;집,&lt;/p&gt;
&lt;p data-end=&quot;1409&quot; data-start=&quot;1406&quot; data-ke-size=&quot;size16&quot;&gt;직장,&lt;/p&gt;
&lt;p data-end=&quot;1420&quot; data-start=&quot;1411&quot; data-ke-size=&quot;size16&quot;&gt;자주 가는 장소,&lt;/p&gt;
&lt;p data-end=&quot;1440&quot; data-start=&quot;1422&quot; data-ke-size=&quot;size16&quot;&gt;생활 시간대까지 추측할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1484&quot; data-start=&quot;1442&quot; data-ke-size=&quot;size16&quot;&gt;그래서 데이터는 하나의 값보다&lt;br /&gt;&lt;b&gt;패턴이 되었을 때 훨씬 강력해진다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1489&quot; data-start=&quot;1486&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1513&quot; data-start=&quot;1491&quot; data-ke-size=&quot;size26&quot;&gt;연락처는 나 혼자만의 정보도 아니다&lt;/h2&gt;
&lt;p data-end=&quot;1540&quot; data-start=&quot;1515&quot; data-ke-size=&quot;size16&quot;&gt;연락처 권한은 조금 더 생각해볼 부분이 있다.&lt;/p&gt;
&lt;p data-end=&quot;1566&quot; data-start=&quot;1542&quot; data-ke-size=&quot;size16&quot;&gt;내 연락처에는 내 정보만 있는 것이 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1571&quot; data-start=&quot;1568&quot; data-ke-size=&quot;size16&quot;&gt;가족,&lt;/p&gt;
&lt;p data-end=&quot;1576&quot; data-start=&quot;1573&quot; data-ke-size=&quot;size16&quot;&gt;친구,&lt;/p&gt;
&lt;p data-end=&quot;1584&quot; data-start=&quot;1578&quot; data-ke-size=&quot;size16&quot;&gt;회사 사람,&lt;/p&gt;
&lt;p data-end=&quot;1601&quot; data-start=&quot;1586&quot; data-ke-size=&quot;size16&quot;&gt;거래처의 정보도 들어 있다.&lt;/p&gt;
&lt;p data-end=&quot;1650&quot; data-start=&quot;1603&quot; data-ke-size=&quot;size16&quot;&gt;물론 운영체제와 앱은 권한을 제한하고 사용자가 제어할 수 있도록 계속 발전하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;1696&quot; data-start=&quot;1652&quot; data-ke-size=&quot;size16&quot;&gt;그렇다고 해서 우리가 아무 생각 없이 모든 권한을 허용해도 된다는 뜻은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1749&quot; data-start=&quot;1698&quot; data-ke-size=&quot;size16&quot;&gt;내가 누른 버튼 하나가&lt;br /&gt;때로는 나 외의 사람과 관련된 정보에도 연결될 수 있기 때문이다.&lt;/p&gt;
&lt;hr data-end=&quot;1754&quot; data-start=&quot;1751&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1784&quot; data-start=&quot;1756&quot; data-ke-size=&quot;size26&quot;&gt;마이크가 무섭다는 이야기를 하려는 것은 아니다&lt;/h2&gt;
&lt;p data-end=&quot;1815&quot; data-start=&quot;1786&quot; data-ke-size=&quot;size16&quot;&gt;이런 이야기를 하면 가끔 극단적인 방향으로 흘러간다.&lt;/p&gt;
&lt;p data-end=&quot;1844&quot; data-start=&quot;1817&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;스마트폰이 항상 우리 대화를 듣는 것 아니야?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;1870&quot; data-start=&quot;1846&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;앱들이 전부 우리를 감시하는 것 아니야?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;1894&quot; data-start=&quot;1872&quot; data-ke-size=&quot;size16&quot;&gt;나는 그런 이야기를 하려는 것이 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1934&quot; data-start=&quot;1896&quot; data-ke-size=&quot;size16&quot;&gt;근거 없이 모든 기술을 의심하는 것도 좋은 태도는 아니라고 생각한다.&lt;/p&gt;
&lt;p data-end=&quot;1962&quot; data-start=&quot;1936&quot; data-ke-size=&quot;size16&quot;&gt;내가 더 관심 있는 것은 훨씬 단순한 부분이다.&lt;/p&gt;
&lt;p data-end=&quot;1993&quot; data-start=&quot;1964&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;우리는 어떤 권한을 주고 있는지 알고 있을까?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1998&quot; data-start=&quot;1995&quot; data-ke-size=&quot;size16&quot;&gt;그리고&lt;/p&gt;
&lt;p data-end=&quot;2032&quot; data-start=&quot;2000&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그 권한이 정말 필요한지 한 번이라도 생각해봤을까?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2045&quot; data-start=&quot;2034&quot; data-ke-size=&quot;size16&quot;&gt;그 정도의 질문이다.&lt;/p&gt;
&lt;hr data-end=&quot;2050&quot; data-start=&quot;2047&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2079&quot; data-start=&quot;2052&quot; data-ke-size=&quot;size26&quot;&gt;기술이 무서운 이유는 기술이 나빠서가 아니다&lt;/h2&gt;
&lt;p data-end=&quot;2093&quot; data-start=&quot;2081&quot; data-ke-size=&quot;size16&quot;&gt;나는 기술을 좋아한다.&lt;/p&gt;
&lt;p data-end=&quot;2101&quot; data-start=&quot;2095&quot; data-ke-size=&quot;size16&quot;&gt;개발자이고,&lt;/p&gt;
&lt;p data-end=&quot;2120&quot; data-start=&quot;2103&quot; data-ke-size=&quot;size16&quot;&gt;새로운 AI 서비스도 사용하고,&lt;/p&gt;
&lt;p data-end=&quot;2135&quot; data-start=&quot;2122&quot; data-ke-size=&quot;size16&quot;&gt;자동화 기술도 좋아한다.&lt;/p&gt;
&lt;p data-end=&quot;2171&quot; data-start=&quot;2137&quot; data-ke-size=&quot;size16&quot;&gt;오히려 기술이 만들어주는 편리함을 적극적으로 사용하는 편이다.&lt;/p&gt;
&lt;p data-end=&quot;2192&quot; data-start=&quot;2173&quot; data-ke-size=&quot;size16&quot;&gt;그래서 더 재미있는 역설이 생긴다.&lt;/p&gt;
&lt;p data-end=&quot;2221&quot; data-start=&quot;2194&quot; data-ke-size=&quot;size16&quot;&gt;기술이 발전할수록 우리가 얻는 편리함도 커지지만,&lt;/p&gt;
&lt;p data-end=&quot;2252&quot; data-start=&quot;2223&quot; data-ke-size=&quot;size16&quot;&gt;동시에 기술이 처리할 수 있는 데이터의 양도 커진다.&lt;/p&gt;
&lt;p data-end=&quot;2284&quot; data-start=&quot;2254&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 사람이 사진 수천 장을 일일이 확인해야 했다.&lt;/p&gt;
&lt;p data-end=&quot;2315&quot; data-start=&quot;2286&quot; data-ke-size=&quot;size16&quot;&gt;지금은 AI가 매우 빠르게 이미지를 분석할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2345&quot; data-start=&quot;2317&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 수많은 텍스트를 사람이 직접 읽어야 했다.&lt;/p&gt;
&lt;p data-end=&quot;2374&quot; data-start=&quot;2347&quot; data-ke-size=&quot;size16&quot;&gt;지금은 시스템이 내용을 분류하고 요약할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2386&quot; data-start=&quot;2376&quot; data-ke-size=&quot;size16&quot;&gt;기술이 똑똑해질수록&lt;/p&gt;
&lt;p data-end=&quot;2418&quot; data-start=&quot;2388&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;데이터가 가지고 있는 가치도 함께 커지고 있다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;2423&quot; data-start=&quot;2420&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2454&quot; data-start=&quot;2425&quot; data-ke-size=&quot;size26&quot;&gt;그래서 이제는 &amp;lsquo;허용&amp;rsquo;을 조금 다르게 보고 있다&lt;/h2&gt;
&lt;p data-end=&quot;2481&quot; data-start=&quot;2456&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 권한 요청이 나오면 이렇게 생각했다.&lt;/p&gt;
&lt;blockquote data-end=&quot;2497&quot; data-start=&quot;2483&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2497&quot; data-start=&quot;2485&quot; data-ke-size=&quot;size16&quot;&gt;귀찮네.&lt;br /&gt;허용.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2517&quot; data-start=&quot;2499&quot; data-ke-size=&quot;size16&quot;&gt;지금은 한 번 정도 더 생각한다.&lt;/p&gt;
&lt;p data-end=&quot;2539&quot; data-start=&quot;2519&quot; data-ke-size=&quot;size16&quot;&gt;이 앱이 사진 전체에 접근해야 할까?&lt;/p&gt;
&lt;p data-end=&quot;2555&quot; data-start=&quot;2541&quot; data-ke-size=&quot;size16&quot;&gt;위치를 항상 알아야 할까?&lt;/p&gt;
&lt;p data-end=&quot;2576&quot; data-start=&quot;2557&quot; data-ke-size=&quot;size16&quot;&gt;이 기능에 연락처가 정말 필요할까?&lt;/p&gt;
&lt;p data-end=&quot;2598&quot; data-start=&quot;2578&quot; data-ke-size=&quot;size16&quot;&gt;마이크를 계속 사용할 이유가 있을까?&lt;/p&gt;
&lt;p data-end=&quot;2614&quot; data-start=&quot;2600&quot; data-ke-size=&quot;size16&quot;&gt;몇 초밖에 걸리지 않는다.&lt;/p&gt;
&lt;p data-end=&quot;2645&quot; data-start=&quot;2616&quot; data-ke-size=&quot;size16&quot;&gt;그리고 필요하다면 나중에 권한을 다시 줄 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;2673&quot; data-start=&quot;2647&quot; data-ke-size=&quot;size16&quot;&gt;중요한 것은 모든 권한을 차단하는 것이 아니다.&lt;/p&gt;
&lt;p data-end=&quot;2697&quot; data-start=&quot;2675&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;필요한 만큼만 허용하는 습관&lt;/b&gt;이다.&lt;/p&gt;
&lt;hr data-end=&quot;2702&quot; data-start=&quot;2699&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2724&quot; data-start=&quot;2704&quot; data-ke-size=&quot;size26&quot;&gt;지금 한 번 확인해보면 재미있다&lt;/h2&gt;
&lt;p data-end=&quot;2754&quot; data-start=&quot;2726&quot; data-ke-size=&quot;size16&quot;&gt;스마트폰 설정을 열어서 앱 권한을 한 번 살펴보자.&lt;/p&gt;
&lt;p data-end=&quot;2767&quot; data-start=&quot;2756&quot; data-ke-size=&quot;size16&quot;&gt;생각보다 의외의 앱이&lt;/p&gt;
&lt;p data-end=&quot;2772&quot; data-start=&quot;2769&quot; data-ke-size=&quot;size16&quot;&gt;사진,&lt;/p&gt;
&lt;p data-end=&quot;2777&quot; data-start=&quot;2774&quot; data-ke-size=&quot;size16&quot;&gt;위치,&lt;/p&gt;
&lt;p data-end=&quot;2783&quot; data-start=&quot;2779&quot; data-ke-size=&quot;size16&quot;&gt;마이크,&lt;/p&gt;
&lt;p data-end=&quot;2816&quot; data-start=&quot;2785&quot; data-ke-size=&quot;size16&quot;&gt;연락처 등에 접근할 수 있도록 설정되어 있을지도 모른다.&lt;/p&gt;
&lt;p data-end=&quot;2822&quot; data-start=&quot;2818&quot; data-ke-size=&quot;size16&quot;&gt;그중에서&lt;/p&gt;
&lt;p data-end=&quot;2844&quot; data-start=&quot;2824&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이 앱이 왜 이 권한이 필요하지?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;2879&quot; data-start=&quot;2846&quot; data-ke-size=&quot;size16&quot;&gt;라는 생각이 드는 것이 있다면&lt;br /&gt;그때 다시 판단하면 된다.&lt;/p&gt;
&lt;p data-end=&quot;2891&quot; data-start=&quot;2881&quot; data-ke-size=&quot;size16&quot;&gt;필요하면 유지하고,&lt;/p&gt;
&lt;p data-end=&quot;2905&quot; data-start=&quot;2893&quot; data-ke-size=&quot;size16&quot;&gt;필요하지 않으면 끈다.&lt;/p&gt;
&lt;p data-end=&quot;2915&quot; data-start=&quot;2907&quot; data-ke-size=&quot;size16&quot;&gt;아주 단순하다.&lt;/p&gt;
&lt;hr data-end=&quot;2920&quot; data-start=&quot;2917&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2944&quot; data-start=&quot;2922&quot; data-ke-size=&quot;size26&quot;&gt;기술을 쓰지 말자는 이야기가 아니다&lt;/h2&gt;
&lt;p data-end=&quot;2964&quot; data-start=&quot;2946&quot; data-ke-size=&quot;size16&quot;&gt;기술은 점점 더 편리해질 것이다.&lt;/p&gt;
&lt;p data-end=&quot;2991&quot; data-start=&quot;2966&quot; data-ke-size=&quot;size16&quot;&gt;AI는 더 많은 데이터를 이해하게 될 것이고,&lt;/p&gt;
&lt;p data-end=&quot;3010&quot; data-start=&quot;2993&quot; data-ke-size=&quot;size16&quot;&gt;서비스들은 더 개인화될 것이다.&lt;/p&gt;
&lt;p data-end=&quot;3027&quot; data-start=&quot;3012&quot; data-ke-size=&quot;size16&quot;&gt;그리고 우리는 앞으로도 계속&lt;/p&gt;
&lt;p data-end=&quot;3037&quot; data-start=&quot;3029&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;lsquo;허용&amp;rsquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3053&quot; data-start=&quot;3039&quot; data-ke-size=&quot;size16&quot;&gt;버튼을 누르게 될 것이다.&lt;/p&gt;
&lt;p data-end=&quot;3101&quot; data-start=&quot;3055&quot; data-ke-size=&quot;size16&quot;&gt;그래서 기술을 피하는 것보다&lt;br /&gt;기술을 알고 사용하는 것이 더 중요하다고 생각한다.&lt;/p&gt;
&lt;p data-end=&quot;3127&quot; data-start=&quot;3103&quot; data-ke-size=&quot;size16&quot;&gt;편리함을 얻는 대신 무엇을 제공하고 있는지,&lt;/p&gt;
&lt;p data-end=&quot;3150&quot; data-start=&quot;3129&quot; data-ke-size=&quot;size16&quot;&gt;적어도 그것만큼은 알고 있었으면 한다.&lt;/p&gt;
&lt;p data-end=&quot;3178&quot; data-start=&quot;3152&quot; data-ke-size=&quot;size16&quot;&gt;나 역시 매번 완벽하게 확인하는 사람은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;3202&quot; data-start=&quot;3180&quot; data-ke-size=&quot;size16&quot;&gt;여전히 귀찮으면 허용을 누를 때도 있다.&lt;/p&gt;
&lt;p data-end=&quot;3224&quot; data-start=&quot;3204&quot; data-ke-size=&quot;size16&quot;&gt;다만 예전과 달라진 점이 하나 있다.&lt;/p&gt;
&lt;p data-end=&quot;3249&quot; data-start=&quot;3226&quot; data-ke-size=&quot;size16&quot;&gt;이제 그 작은 버튼이 조금 다르게 보인다.&lt;/p&gt;
&lt;p data-end=&quot;3298&quot; data-start=&quot;3251&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;앱을 설치할 때마다&lt;br /&gt;우리는 우리의 일부를 조금씩 보여주고 있을지도 모른다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3314&quot; data-start=&quot;3300&quot; data-ke-size=&quot;size16&quot;&gt;그래서 가끔은 묻게 된다.&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;3341&quot; data-start=&quot;3316&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;이 앱에게 여기까지 보여줘도 될까?&amp;rdquo;&lt;/b&gt;&lt;/p&gt;</description>
      <category>기술이 조금 무섭다</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/13</guid>
      <comments>https://nocklock.tistory.com/13#entry13comment</comments>
      <pubDate>Sat, 19 Sep 2026 11:30:20 +0900</pubDate>
    </item>
    <item>
      <title>프론트엔드를 붙였더니, 드디어 서비스처럼 보이기 시작했다 | RE:개발자 #7</title>
      <link>https://nocklock.tistory.com/11</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;프론트엔드가 붙으니 비로소 서비스처럼 보였다&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 17일 오전 10_13_45.png&quot; data-origin-width=&quot;1731&quot; data-origin-height=&quot;909&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcAzGm/dJMb992eIgF/4bfmq6nvRpyDU4vjAxWA80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcAzGm/dJMb992eIgF/4bfmq6nvRpyDU4vjAxWA80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcAzGm/dJMb992eIgF/4bfmq6nvRpyDU4vjAxWA80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcAzGm%2FdJMb992eIgF%2F4bfmq6nvRpyDU4vjAxWA80%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; alt=&quot;프론트엔드&quot; loading=&quot;lazy&quot; width=&quot;1731&quot; height=&quot;909&quot; data-filename=&quot;ChatGPT Image 2026년 9월 17일 오전 10_13_45.png&quot; data-origin-width=&quot;1731&quot; data-origin-height=&quot;909&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;백엔드 기능을 어느 정도 완성하고 나니 조금 이상한 기분이 들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이미지 업로드도 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;OCR도 동작한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사진 안에서 전화번호나 이메일 같은 개인정보도 찾을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;EXIF 데이터를 읽어 GPS 위치나 촬영 시간, 기기 정보도 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;위험 점수까지 계산해서 JSON으로 정상적으로 내려온다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개발자인 내가 보기에는 분명히 기능이 만들어지고 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 화면을 보는 순간 생각이 달라졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;브라우저에는 JSON만 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;riskScore&quot;: 82,
  &quot;riskLevel&quot;: &quot;CRITICAL&quot;,
  &quot;detectedItems&quot;: [
    {
      &quot;type&quot;: &quot;PHONE_NUMBER&quot;,
      &quot;value&quot;: &quot;010-****-5678&quot;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기능은 있었지만, 아직 이것을 일반 사용자가 사용할 수 있는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;서비스&lt;/span&gt;&lt;/b&gt;&lt;span&gt;라고 부르기는 어려웠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 이번에는 프론트엔드를 붙이기로 했다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;문제는 내가 프론트엔드 개발자가 아니라는 것&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;나는 주로 Java, Spring MVC, JSP를 사용해 웹 서비스를 개발해왔다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;물론 HTML, CSS, JavaScript를 사용하지 않은 것은 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JSP 안에서 화면을 만들고 jQuery와 Ajax를 사용해 서버와 데이터를 주고받는 작업도 많이 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 이번처럼&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;HTML
CSS
Vanilla JavaScript&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;를 기준으로 화면 전체를 처음부터 설계하는 작업은 익숙하지 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;특히 디자인은 더 어려웠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;버튼 하나를 어디에 둬야 자연스러운지,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과 화면에서 어떤 정보부터 보여줘야 하는지,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;위험 점수를 숫자로만 보여줄지 그래프로 보여줄지,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;모바일에서는 화면을 어떻게 배치해야 할지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;백엔드에서는 기능의 정답이 어느 정도 보이는데 프론트엔드는 선택해야 할 것이 훨씬 많았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 이번에는 AI를 적극적으로 사용했다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;ChatGPT에게는 화면의 방향을 맡겼다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;먼저 ChatGPT와 프로젝트의 사용 흐름을 정리했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사용자가 해야 하는 행동은 사실 단순했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;사진 선택
&amp;darr;
분석 버튼 클릭
&amp;darr;
백엔드 API 호출
&amp;darr;
분석 결과 확인&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;페이지가 여러 개 필요한 서비스도 아니었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 React나 Vue 같은 프레임워크를 새롭게 도입하기보다 Spring Boot 안에서 간단하게 프론트엔드를 구성하기로 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;구조는 이렇게 잡았다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;src
 └─ main
     └─ resources
         └─ static
             ├─ index.html
             ├─ style.css
             └─ app.js&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;index.html&lt;/span&gt;&lt;span&gt;은 화면의 구조,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;style.css&lt;/span&gt;&lt;span&gt;는 디자인,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;app.js&lt;/span&gt;&lt;span&gt;는 API 호출과 화면 변경을 담당하도록 역할을 분리했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 구조를 잡고 나니 생각보다 단순했다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;HTML부터 시작했다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처음에는 정말 최소한의 화면부터 만들었다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;input
    type=&quot;file&quot;
    id=&quot;imageInput&quot;
    accept=&quot;image/*&quot;
/&amp;gt;

&amp;lt;button id=&quot;analyzeButton&quot;&amp;gt;
    분석하기
&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사진을 선택하고 분석 버튼을 누르는 것이 전부였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 여기서부터 사용자의 입장에서 생각하기 시작했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사진을 어디에 올려야 하는지 바로 알 수 있어야 하고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 선택한 사진이 무엇인지 보여줘야 하고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;분석 중인지 완료됐는지도 알려줘야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 단순한 파일 입력창을 업로드 영역으로 바꿨다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;┌───────────────────────────────┐

        사진을 업로드하세요

       JPG / PNG / WEBP

        [ 사진 선택하기 ]

└───────────────────────────────┘

        [ 분석하기 ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;드래그 앤 드롭도 가능하도록 만들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그제야 조금씩 서비스처럼 보이기 시작했다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;JavaScript가 백엔드와 프론트엔드를 연결했다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개인적으로 이번에 가장 재미있었던 부분이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예전에 JSP 기반 개발을 할 때는 서버가 화면 생성에 많이 관여했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에는 역할이 훨씬 명확했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Spring Boot는 데이터를 전달하고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JavaScript가 데이터를 받아 화면을 변경한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 이미지 분석 API를 호출하는 부분은 이런 구조다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;async function analyzeImage() {

    const file = imageInput.files[0];

    const formData = new FormData();

    formData.append(&quot;image&quot;, file);

    const response = await fetch(&quot;/api/analyze&quot;, {
        method: &quot;POST&quot;,
        body: formData
    });

    const result = await response.json();

    renderResult(result);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;백엔드에서&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;riskScore&quot;: 82,
  &quot;riskLevel&quot;: &quot;CRITICAL&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이라는 응답이 오면 JavaScript가 이것을 화면에 표시한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;riskScore.textContent = result.riskScore;
riskLevel.textContent = result.riskLevel;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사실 코드 자체만 보면 복잡하지 않다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 이 연결이 되는 순간 꽤 재미있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;내가 만들어놓은 Java API가 처음으로 일반 사용자가 볼 수 있는 화면과 연결됐기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Claude는 구현 보조로 사용했다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;ChatGPT와는 화면 구조와 사용자 흐름을 계속 이야기했다면 Claude는 구현 과정에서 코드 단위로 많이 활용했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;이 부분을 조금 더 정리할 수 있을까?

JavaScript 이벤트 처리가 중복되는데
함수를 어떻게 나누는 게 좋을까?

CSS에서 모바일 화면이 무너지는 이유가 뭘까?&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;같은 질문을 던졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI에게 전체 프로젝트를 통째로 맡긴 것은 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;내가 먼저&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;이 화면에는 무엇이 필요한가?
이 기능은 왜 필요한가?
백엔드 데이터는 어떤 구조인가?&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;를 결정하고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;구현하면서 막히는 부분을 AI에게 계속 물어봤다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;ChatGPT와 Claude를 번갈아 사용하다 보니 재미있는 점도 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;같은 문제를 물어봐도 접근 방식이 조금씩 달랐다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그중에서 내가 이해할 수 있고 현재 프로젝트에 맞는 코드를 선택해서 적용했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결국 AI가 코드를 작성했다기보다는&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;AI와 계속 대화하면서 내가 코드를 완성했다&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;는 표현이 더 맞는 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;디자인보다 먼저 고민한 것은 접근성이었다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;화면을 만들면서 한 가지는 꼭 지키려고 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;보기에 예쁜 것만으로 끝내지 않는 것.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 클릭할 수 있는 요소라면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;&amp;lt;div onclick=&quot;analyze()&quot;&amp;gt;
    분석하기
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;보다&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;button type=&quot;button&quot;&amp;gt;
    분석하기
&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처럼 의미에 맞는 태그를 사용하는 것이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이미지에도 필요한 경우 &lt;/span&gt;&lt;span&gt;alt&lt;/span&gt;&lt;span&gt; 설명을 넣고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;입력 요소에는 &lt;/span&gt;&lt;span&gt;label&lt;/span&gt;&lt;span&gt;을 연결했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;&amp;lt;label for=&quot;imageInput&quot;&amp;gt;
    분석할 사진 선택
&amp;lt;/label&amp;gt;

&amp;lt;input
    id=&quot;imageInput&quot;
    type=&quot;file&quot;
    accept=&quot;image/*&quot;
/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;한국에는 장애인차별금지법과 웹 접근성 기준이 있고 해외 서비스에서도 접근성은 중요한 부분이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번 프로젝트 규모에서는 작은 부분일 수 있지만 처음부터 습관으로 가져가고 싶었다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;화면 하나가 생겼을 뿐인데 프로젝트가 완전히 달라졌다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사실 기능이 추가된 것은 거의 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;백엔드는 어제와 똑같이 동작한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;OCR도 그대로이고 개인정보 탐지 로직도 그대로다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 화면 하나가 붙었을 뿐인데 느낌이 완전히 달라졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;어제까지는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;API 프로젝트&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;였다면,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;오늘부터는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;사용자가 직접 사용할 수 있는 서비스&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처럼 보이기 시작했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사진을 선택한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;분석 버튼을 누른다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Spring Boot API가 호출된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;OCR과 메타데이터 분석이 진행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 결과가 다시 화면에 나타난다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;내가 만든 각각의 기능이 하나의 흐름으로 연결됐다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;프론트엔드를 잘해야만 서비스를 만들 수 있는 것은 아니었다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사실 시작하기 전에는 프론트엔드가 조금 부담스러웠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;나는 여전히 CSS보다 Java 코드가 편하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;디자인 감각도 뛰어난 편이라고 생각하지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 이번에 다시 느낀 것은 하나다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;모든 것을 잘해야만 시작할 수 있는 것은 아니었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;내가 아는 백엔드 지식을 중심에 두고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;모르는 부분에서는 ChatGPT에게 구조를 물어보고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Claude에게 구현 방법을 확인하고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;코드를 직접 실행하고 수정했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 결국 화면이 만들어졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI가 개발자를 대신한다는 이야기를 많이 듣는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;지금 내가 느끼는 것은 조금 다르다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI는 내가 잘 모르는 영역까지 들어갈 수 있게 해주는 도구에 더 가까웠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;프론트엔드에 익숙하지 않은 Java 개발자가&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;HTML을 만들고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;CSS를 수정하고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JavaScript로 API를 연결하고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결국 실제로 사용할 수 있는 화면까지 만들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예전 같았으면 프론트엔드를 더 공부한 다음 시작해야 한다고 생각했을지도 모르겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에는 반대로 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;만들면서 배웠다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 화면을 완성하고 나서 처음으로 이런 생각이 들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;프론트엔드가 붙으니 비로소 서비스처럼 보였다.&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>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/11</guid>
      <comments>https://nocklock.tistory.com/11#entry11comment</comments>
      <pubDate>Sat, 19 Sep 2026 11:16:32 +0900</pubDate>
    </item>
    <item>
      <title>개발할 때 AI를 이렇게 쓰고 있다, ChatGPT와 Claude 실사용기</title>
      <link>https://nocklock.tistory.com/10</link>
      <description>&lt;p data-end=&quot;146&quot; data-start=&quot;122&quot; data-ke-size=&quot;size16&quot;&gt;요즘 AI 툴을 이것저것 많이 써보고 있다.&lt;/p&gt;
&lt;p data-end=&quot;194&quot; data-start=&quot;148&quot; data-ke-size=&quot;size16&quot;&gt;얼마 전에는 아예 지금 나와 있는 AI 툴들을 한 번 정리해서 글로 올리기도 했다.&lt;/p&gt;
&lt;p data-end=&quot;251&quot; data-start=&quot;196&quot; data-ke-size=&quot;size16&quot;&gt;그런데 막상 내가 실제 개발할 때 어떻게 사용하고 있는지 생각해보니, 툴마다 역할이 조금씩 달랐다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 16일 오후 07_25_26.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkDuMF/dJMcacrcg8Z/T4MwD7sxtkEl7YWUGFx90k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkDuMF/dJMcacrcg8Z/T4MwD7sxtkEl7YWUGFx90k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkDuMF/dJMcacrcg8Z/T4MwD7sxtkEl7YWUGFx90k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkDuMF%2FdJMcacrcg8Z%2FT4MwD7sxtkEl7YWUGFx90k%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;1536&quot; height=&quot;1024&quot; data-filename=&quot;ChatGPT Image 2026년 9월 16일 오후 07_25_26.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;273&quot; data-start=&quot;253&quot; data-ke-size=&quot;size16&quot;&gt;가장 많이 쓰는 건 ChatGPT다.&lt;/p&gt;
&lt;p data-end=&quot;273&quot; data-start=&quot;253&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;331&quot; data-start=&quot;275&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 코드를 물어보는 용도로 많이 썼는데, 요즘은 오히려 개발 방향을 잡을 때 더 많이 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;421&quot; data-start=&quot;333&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트 아이디어가 생기면 기능을 어디까지 만들지, MVP는 어디까지 잡을지, Spring Boot 구조를 어떻게 가져갈지 같은 걸 먼저 대화하면서 정리한다.&lt;/p&gt;
&lt;p data-end=&quot;470&quot; data-start=&quot;423&quot; data-ke-size=&quot;size16&quot;&gt;막연하게 생각했던 아이디어가 대화를 하다 보면 조금씩 구체적인 기능과 구조로 바뀐다.&lt;/p&gt;
&lt;p data-end=&quot;486&quot; data-start=&quot;472&quot; data-ke-size=&quot;size16&quot;&gt;최근 프로젝트도 비슷했다.&lt;/p&gt;
&lt;p data-end=&quot;577&quot; data-start=&quot;488&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 단순한 아이디어였는데, ChatGPT와 이야기하면서 API 구조를 정하고 Controller, Service, DTO 같은 기본 구조까지 다시 잡았다.&lt;/p&gt;
&lt;p data-end=&quot;577&quot; data-start=&quot;488&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;608&quot; data-start=&quot;579&quot; data-ke-size=&quot;size16&quot;&gt;실제 코드 작업은 Claude도 많이 활용하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;608&quot; data-start=&quot;579&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;672&quot; data-start=&quot;610&quot; data-ke-size=&quot;size16&quot;&gt;코드를 새로 만들거나 기존 코드를 정리할 때, 클래스 역할을 나누거나 리팩터링 방향을 잡는 데 꽤 도움이 된다.&lt;/p&gt;
&lt;p data-end=&quot;686&quot; data-start=&quot;674&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 AI에게 그냥&lt;/p&gt;
&lt;p data-end=&quot;699&quot; data-start=&quot;688&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이 코드 만들어줘&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;727&quot; data-start=&quot;701&quot; data-ke-size=&quot;size16&quot;&gt;라고 했다면 지금은 조금 다르게 사용하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;774&quot; data-start=&quot;729&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이 Service가 너무 많은 일을 하는 것 같은데 어떻게 나누는 게 좋을까?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;791&quot; data-start=&quot;776&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이 구조의 단점은 뭐야?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;812&quot; data-start=&quot;793&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;더 단순하게 만들 방법은 없어?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;826&quot; data-start=&quot;814&quot; data-ke-size=&quot;size16&quot;&gt;이런 식으로 질문한다.&lt;/p&gt;
&lt;p data-end=&quot;855&quot; data-start=&quot;828&quot; data-ke-size=&quot;size16&quot;&gt;AI가 만들어준 코드를 그대로 사용하지도 않는다.&lt;/p&gt;
&lt;p data-end=&quot;904&quot; data-start=&quot;857&quot; data-ke-size=&quot;size16&quot;&gt;IDE에서 다시 확인하고, 직접 빌드하고, 실행해보고, 문제가 있으면 다시 수정한다.&lt;/p&gt;
&lt;p data-end=&quot;962&quot; data-start=&quot;906&quot; data-ke-size=&quot;size16&quot;&gt;AI가 빠르게 코드를 만들어주는 건 분명 편하지만, 항상 맞는 코드를 만들어주는 건 아니기 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;1020&quot; data-start=&quot;964&quot; data-ke-size=&quot;size16&quot;&gt;가끔은 필요 이상으로 복잡하게 만들기도 하고, 내가 사용하는 버전과 맞지 않는 코드가 나오기도 한다.&lt;/p&gt;
&lt;p data-end=&quot;1055&quot; data-start=&quot;1022&quot; data-ke-size=&quot;size16&quot;&gt;그래서 요즘에는 AI가 코드를 만들어주면 한 번 더 묻는다.&lt;/p&gt;
&lt;p data-end=&quot;1070&quot; data-start=&quot;1057&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;왜 이렇게 만들었어?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;1093&quot; data-start=&quot;1072&quot; data-ke-size=&quot;size16&quot;&gt;이 질문이 의외로 공부에 도움이 된다.&lt;/p&gt;
&lt;p data-end=&quot;1093&quot; data-start=&quot;1072&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1152&quot; data-start=&quot;1095&quot; data-ke-size=&quot;size16&quot;&gt;예전에 회사에서 그냥 사용했던 Controller, Service, DTO 구조도 다시 생각하게 됐다.&lt;/p&gt;
&lt;p data-end=&quot;1226&quot; data-start=&quot;1154&quot; data-ke-size=&quot;size16&quot;&gt;왜 나누는지, 왜 이런 구조를 사용하는지 설명을 듣고 직접 코드를 수정하다 보면 예전에 알고 있다고 생각했던 부분도 다시 보인다.&lt;/p&gt;
&lt;p data-end=&quot;1289&quot; data-start=&quot;1228&quot; data-ke-size=&quot;size16&quot;&gt;ChatGPT와 Claude 외에도 검색, 문서 정리, 이미지 생성 등 여러 AI 툴을 계속 사용해보고 있다.&lt;/p&gt;
&lt;p data-end=&quot;1316&quot; data-start=&quot;1291&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1316&quot; data-start=&quot;1291&quot; data-ke-size=&quot;size16&quot;&gt;그렇다고 모든 AI를 다 사용할 생각은 없다.&lt;/p&gt;
&lt;p data-end=&quot;1316&quot; data-start=&quot;1291&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1379&quot; data-start=&quot;1318&quot; data-ke-size=&quot;size16&quot;&gt;중요한 건 어떤 AI가 가장 유명한지가 아니라, 지금 내가 하는 작업에 어떤 도구가 도움이 되는지인 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;1400&quot; data-start=&quot;1381&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1400&quot; data-start=&quot;1381&quot; data-ke-size=&quot;size16&quot;&gt;현재 내 개발 방식은 대략 이렇다.&lt;/p&gt;
&lt;p data-end=&quot;1436&quot; data-start=&quot;1402&quot; data-ke-size=&quot;size16&quot;&gt;아이디어를 생각하고, ChatGPT와 기능과 구조를 정리한다.&lt;/p&gt;
&lt;p data-end=&quot;1493&quot; data-start=&quot;1438&quot; data-ke-size=&quot;size16&quot;&gt;그다음 Claude 등의 AI 도구를 이용해 구현을 보조하고, 내가 직접 코드를 확인하고 실행한다.&lt;/p&gt;
&lt;p data-end=&quot;1524&quot; data-start=&quot;1495&quot; data-ke-size=&quot;size16&quot;&gt;문제가 생기면 다시 AI와 원인을 찾아보고 수정한다.&lt;/p&gt;
&lt;p data-end=&quot;1545&quot; data-start=&quot;1526&quot; data-ke-size=&quot;size16&quot;&gt;마지막에는 Git에 기록을 남긴다.&lt;/p&gt;
&lt;p data-end=&quot;1573&quot; data-start=&quot;1547&quot; data-ke-size=&quot;size16&quot;&gt;AI를 사용하면서 개발 속도는 확실히 빨라졌다.&lt;/p&gt;
&lt;p data-end=&quot;1595&quot; data-start=&quot;1575&quot; data-ke-size=&quot;size16&quot;&gt;하지만 동시에 하나 느낀 것도 있다.&lt;/p&gt;
&lt;p data-end=&quot;1595&quot; data-start=&quot;1575&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1632&quot; data-start=&quot;1597&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AI를 잘 쓰려면 결국 내가 더 많이 알아야 한다는 것.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1632&quot; data-start=&quot;1597&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1676&quot; data-start=&quot;1634&quot; data-ke-size=&quot;size16&quot;&gt;코드를 만들어주는 것과 그 코드가 좋은 코드인지 판단하는 것은 다른 문제다.&lt;/p&gt;
&lt;p data-end=&quot;1740&quot; data-start=&quot;1678&quot; data-ke-size=&quot;size16&quot;&gt;무엇을 만들지, 어떤 구조가 적절한지, 보안 문제는 없는지, AI의 답이 맞는지는 결국 개발자가 판단해야 한다.&lt;/p&gt;
&lt;p data-end=&quot;1785&quot; data-start=&quot;1742&quot; data-ke-size=&quot;size16&quot;&gt;그래서 나는 AI에게 개발을 맡긴다기보다는 개발 보조 도구로 사용하려고 한다.&lt;/p&gt;
&lt;p data-end=&quot;1837&quot; data-start=&quot;1787&quot; data-ke-size=&quot;size16&quot;&gt;Java도 다시 공부하고, Spring Boot와 Gradle, Git도 다시 보고 있다.&lt;/p&gt;
&lt;p data-end=&quot;1879&quot; data-start=&quot;1839&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 그냥 사용했던 기술들을 이번에는 조금 더 제대로 이해하고 싶다.&lt;/p&gt;
&lt;p data-end=&quot;1912&quot; data-start=&quot;1881&quot; data-ke-size=&quot;size16&quot;&gt;그리고 그 과정에서 AI도 적극적으로 사용해보려고 한다.&lt;/p&gt;
&lt;p data-end=&quot;2020&quot; data-start=&quot;1992&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AI TOOLS</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/10</guid>
      <comments>https://nocklock.tistory.com/10#entry10comment</comments>
      <pubDate>Fri, 18 Sep 2026 15:25:48 +0900</pubDate>
    </item>
    <item>
      <title>OCR로 개인정보를 찾기 시작했다, 하드코딩을 걷어낸 날 | RE:개발자 #6</title>
      <link>https://nocklock.tistory.com/8</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;하드코딩을 걷어내고, 진짜 분석을 시작했다&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 16일 오후 07_11_51 (2).png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b17ukb/dJMcai5NMk7/l9qRhlcPNKdYGtzWZ17kE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b17ukb/dJMcai5NMk7/l9qRhlcPNKdYGtzWZ17kE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b17ukb/dJMcai5NMk7/l9qRhlcPNKdYGtzWZ17kE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb17ukb%2FdJMcai5NMk7%2Fl9qRhlcPNKdYGtzWZ17kE0%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; alt=&quot;hardcoding&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 16일 오후 07_11_51 (2).png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;지난 편까지 Security Lens의 API는 잘 동작했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;문제는 한 가지였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;분석을 전혀 하지 않는 분석 API였다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;riskScore = 82
riskLevel = CRITICAL&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사진에 무엇이 들어 있든 결과는 똑같았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;오늘은 이 하드코딩을 하나씩 걷어내기 시작했다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;첫 번째 목표는 OCR&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사진 안에서 개인정보를 찾으려면&lt;/span&gt;&lt;br /&gt;&lt;span&gt;일단 사진에 무슨 글자가 적혀 있는지 알아야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 분석 흐름에 OCR을 추가했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;전체 구조는 이렇게 가져가기로 했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;이미지 업로드
      &amp;darr;
이미지 정보 분석
      &amp;darr;
메타데이터 분석
      &amp;darr;
OCR
      &amp;darr;
개인정보 탐지
      &amp;darr;
위험 점수 계산
      &amp;darr;
위험 등급 결정
      &amp;darr;
결과 반환&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;조금씩 진짜 서비스 같은 구조가 만들어지기 시작했다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;analyzer 패키지를 만들었다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 오늘 새롭게 만든 것 중 하나가&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;analyzer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;패키지다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Service 안에 전화번호 정규식, 이메일 정규식, 주소 탐지 로직을 전부 넣어버릴 수도 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 그렇게 시작하면 금방 코드가 커질 것 같았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 역할을 분리했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;service
 ├─ ImageAnalysisService
 ├─ ImageMetadataService
 └─ OcrService

analyzer
 └─ PiiAnalyzer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;여기서 PII는&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;Personally Identifiable Information&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;즉, 개인을 식별할 수 있는 정보를 의미한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Security Lens에서 굉장히 중요한 개념이다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;OCR 결과에서 개인정보를 찾아보자&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;OCR이 이미지의 텍스트를 읽었다고 끝나는 것은 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 OCR 결과가&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;홍길동
서울시 서초구 어딘가
010-1234-5678
hello@example.com&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이렇게 나왔다고 하자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이제 여기에서 개인정보를 찾아야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;첫 번째 버전에서는 너무 복잡하게 가지 않고&lt;/span&gt;&lt;br /&gt;&lt;span&gt;정규식을 사용하기로 했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dart&quot;&gt;&lt;code&gt;전화번호 &amp;rarr; Pattern
이메일   &amp;rarr; Pattern
주소     &amp;rarr; Pattern&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 &lt;/span&gt;&lt;span&gt;PiiAnalyzer&lt;/span&gt;&lt;span&gt;가 OCR 결과를 받아&lt;/span&gt;&lt;br /&gt;&lt;span&gt;개인정보 후보를 찾아낸다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;처음부터 AI를 사용하지 않은 이유&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사실 이런 프로젝트를 만들면 바로 이런 생각이 든다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&quot;그냥 LLM한테 보내면 되는 거 아닌가?&quot;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;물론 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 나중에는 AI 분석도 붙일 예정이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 처음부터 모든 걸 AI에게 맡기고 싶지는 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;전화번호처럼 규칙이 명확한 개인정보는&lt;/span&gt;&lt;br /&gt;&lt;span&gt;굳이 LLM에게 물어볼 필요가 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;010-1234-5678&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;같은 데이터는 정규식으로도 충분히 찾을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 현재 방향은&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;규칙으로 찾을 수 있는 것
        &amp;darr;
정규식 / 로직

규칙으로 판단하기 어려운 것
        &amp;darr;
AI&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이런 구조다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개인적으로 이쪽이 더 재미있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;단순히 AI API를 호출하는 서비스를 만드는 게 아니라&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;기존 프로그램 로직과 AI를 어디에서 나눌 것인지&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;고민할 수 있기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;이제 점수도 계산한다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기존에는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;82&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;라고 적혀 있던 위험 점수도&lt;/span&gt;&lt;br /&gt;&lt;span&gt;실제 분석 결과를 기반으로 계산하도록 구조를 바꿨다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 &lt;/span&gt;&lt;span&gt;ImageAnalysisService&lt;/span&gt;&lt;span&gt;의 흐름은 대략 이런 식이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;ImageAnalysisService

1. 이미지 정보 추출
2. Metadata 추출
3. OCR 실행
4. PII 분석
5. Risk Score 계산
6. Risk Level 결정
7. AnalysisResponse 생성&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 각 기능을 하나의 클래스에 몰아넣지 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;OcrService
PiiAnalyzer
RiskScoreCalculator
ImageMetadataService&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;각자 하나의 역할을 담당하게 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예전에는 이런 구조를 보면&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&quot;클래스가 왜 이렇게 많지?&quot;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;라고 생각했는데,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;지금 다시 만들어보니 오히려 반대다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;역할이 나뉘어 있으니까&lt;/span&gt;&lt;br /&gt;&lt;span&gt;어디를 수정해야 하는지가 훨씬 명확하다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;아직 완성된 것은 아니다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 PII 탐지는 MVP 단계다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;전화번호, 이메일, 주소처럼&lt;/span&gt;&lt;br /&gt;&lt;span&gt;형식이 비교적 명확한 정보부터 찾고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 OCR 자체도 항상 정확하지 않다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;010-1234-5678&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;을&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;O1O-1234-567B&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처럼 읽어버릴 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그러면 정규식은 전화번호라고 판단하지 못한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;앞으로 해결해야 할 문제가 꽤 많다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 그게 오히려 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이제부터는 단순히 CRUD 화면을 하나 만드는 것이 아니라&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;OCR 정확도
&amp;rarr; 개인정보 탐지
&amp;rarr; AI 분석
&amp;rarr; 위험도 산정
&amp;rarr; 결과 설명&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;같은 문제를 하나씩 해결해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;다시 개발자가 되어가는 느낌&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;오늘 개발하면서 재미있었던 부분은&lt;/span&gt;&lt;br /&gt;&lt;span&gt;단순히 코드가 돌아간다는 게 아니었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처음에는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;riskScore = 82;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;였던 코드가&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;이미지
 &amp;darr;
OCR
 &amp;darr;
분석
 &amp;darr;
점수 계산&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이라는 구조로 변해가는 과정이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;작은 변화지만,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;하드코딩된 숫자 하나가 실제 로직의 결과로 바뀌는 순간&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;프로그램이 조금 살아나는 느낌이 든다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예전에 회사에서 개발할 때는&lt;/span&gt;&lt;br /&gt;&lt;span&gt;주어진 요구사항을 구현하는 데 집중했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;지금은 내가 직접&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;어떤 구조로 만들어야 할까?&lt;/span&gt;&lt;br /&gt;&lt;span&gt;어디까지 Java가 해야 할까?&lt;/span&gt;&lt;br /&gt;&lt;span&gt;어디서 AI를 써야 할까?&lt;/span&gt;&lt;br /&gt;&lt;span&gt;개인정보를 어떤 기준으로 위험하다고 판단해야 할까?&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;를 결정해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 어렵지만 훨씬 재미있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;오늘 Security Lens는&lt;/span&gt;&lt;br /&gt;&lt;span&gt;단순한 Mock API에서 한 단계 벗어났다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;아직 작은 분석기지만,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;이제 정말 이미지를 보기 시작했다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/8</guid>
      <comments>https://nocklock.tistory.com/8#entry8comment</comments>
      <pubDate>Fri, 18 Sep 2026 08:13:10 +0900</pubDate>
    </item>
    <item>
      <title>Spring Boot로 REST API를 만들었는데, 아직 아무것도 분석하지 않았다 | RE:개발자 #5</title>
      <link>https://nocklock.tistory.com/7</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;API는 만들었는데, 아직 아무것도 분석하지 않았다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;오늘은 내가 만들고 있는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Security Lens&lt;/span&gt;&lt;/b&gt;&lt;span&gt;의 구조를 조금 더 제대로 잡아봤다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 16일 오후 07_11_51 (1).png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sQw3B/dJMcac5FHfl/sfU1DNB6CKZcwUWuZhLUcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sQw3B/dJMcac5FHfl/sfU1DNB6CKZcwUWuZhLUcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sQw3B/dJMcac5FHfl/sfU1DNB6CKZcwUWuZhLUcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsQw3B%2FdJMcac5FHfl%2FsfU1DNB6CKZcwUWuZhLUcK%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; alt=&quot;API&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 16일 오후 07_11_51 (1).png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Security Lens는 사진을 업로드하면&lt;/span&gt;&lt;br /&gt;&lt;span&gt;그 이미지 안에 개인정보가 얼마나 포함되어 있는지 분석하고 위험도를 알려주는 프로젝트다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;전화번호, 주소 같은 정보부터&lt;/span&gt;&lt;br /&gt;&lt;span&gt;나중에는 이미지 속에서 추론할 수 있는 정보까지 분석해보는 게 목표다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 기능을 만들기 전에 먼저 해야 할 일이 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;API의 뼈대부터 만드는 것.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;예전에는 그냥 Controller부터 만들었다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;회사에서 개발할 때도 Spring MVC를 사용했기 때문에&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Controller &amp;rarr; Service &amp;rarr; DTO&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;같은 구조가 낯설지는 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다만 당시에는 이미 만들어져 있는 프로젝트 안에서 기능을 추가하는 경우가 많았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에는 처음부터 내가 구조를 만들어야 했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;이미지 업로드
     &amp;darr;
Controller
     &amp;darr;
Service
     &amp;darr;
분석
     &amp;darr;
DTO
     &amp;darr;
JSON 응답&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;구조 자체는 단순하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 직접 만들어보니 예전에 그냥 사용하던 코드들이 다시 보이기 시작했다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Controller는 요청을 받는다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이미지를 업로드하면 Controller가 &lt;/span&gt;&lt;span&gt;MultipartFile&lt;/span&gt;&lt;span&gt;로 파일을 받는다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;@PostMapping(&quot;/analyze&quot;)
public AnalysisResponse analyze(
        @RequestParam(&quot;image&quot;) MultipartFile image) {

    return imageAnalysisService.analyze(image);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Controller가 직접 개인정보를 찾거나&lt;/span&gt;&lt;br /&gt;&lt;span&gt;위험도를 계산하도록 만들지는 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Controller의 역할은 최대한 단순하게.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;요청을 받고 Service에게 넘긴다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;Service에서 실제 작업을 한다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;분석 과정은 &lt;/span&gt;&lt;span&gt;ImageAnalysisService&lt;/span&gt;&lt;span&gt;에서 관리하도록 만들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 결과를 JSON으로 반환하기 위해 여러 DTO도 만들었다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;AnalysisResponse
 ├─ riskScore
 ├─ riskLevel
 ├─ imageInfo
 ├─ detectedItems
 ├─ metadata
 ├─ inferences
 └─ summary&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Java 17을 다시 공부하는 과정이기도 해서 DTO는 &lt;/span&gt;&lt;span&gt;record&lt;/span&gt;&lt;span&gt;를 사용했다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;public record AnalysisResponse(
        int riskScore,
        RiskLevel riskLevel,
        ImageInfo image,
        List&amp;lt;DetectedItem&amp;gt; detectedItems,
        MetadataResult metadata,
        List&amp;lt;InferenceResult&amp;gt; inferences,
        String summary
) {}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예전에 Java로 개발할 때였다면&lt;/span&gt;&lt;br /&gt;&lt;span&gt;필드 만들고 Getter 만들고 생성자 만들고 있었을 텐데,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;record&lt;/span&gt;&lt;span&gt;를 사용하니 이런 데이터 전달용 객체가 훨씬 간결해졌다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;그런데 응답은 가짜였다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;API를 호출하면 이런 결과가 나왔다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;riskScore&quot;: 82,
  &quot;riskLevel&quot;: &quot;CRITICAL&quot;,
  &quot;detectedItems&quot;: [
    {
      &quot;type&quot;: &quot;PHONE_NUMBER&quot;,
      &quot;value&quot;: &quot;010-****-5678&quot;,
      &quot;confidence&quot;: 0.99
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그럴듯하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 문제가 하나 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;전부 하드코딩이다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사진에 전화번호가 없어도 전화번호가 나온다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;점수도 무조건 82점이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처음에는 조금 이상한 느낌이 들었다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&quot;이거 그냥 가짜 API 아닌가?&quot;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 생각해보면 이것도 개발 과정이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;먼저&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;요청 &amp;rarr; 처리 &amp;rarr; 응답&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;전체 흐름을 만든 다음,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그 안의 가짜 데이터를 실제 기능으로 하나씩 교체하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;그리고 빌드&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;집에서 작업한 코드를 GitHub에 올리고&lt;/span&gt;&lt;br /&gt;&lt;span&gt;다른 PC에서 다시 &lt;/span&gt;&lt;span&gt;git pull&lt;/span&gt;&lt;span&gt;을 받았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 Gradle 빌드.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;excel&quot;&gt;&lt;code&gt;./gradlew clean build&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;BUILD SUCCESSFUL&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;컴파일부터 테스트, 패키징까지 정상적으로 통과했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;작은 메시지인데 이상하게 기분이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예전에는 너무 당연하게 지나쳤던 문구였는데&lt;/span&gt;&lt;br /&gt;&lt;span&gt;지금은 내가 프로젝트를 하나씩 다시 만들어가고 있다는 느낌이 든다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;오늘 다시 배운 것&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Spring Boot를 다시 공부하면서 느끼는 건&lt;/span&gt;&lt;br /&gt;&lt;span&gt;새로운 기술을 배우고 있다기보다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;예전에 사용하던 기술을 이제야 구조적으로 이해하고 있다는 것&lt;/span&gt;&lt;/b&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;회사에서는 기능 구현이 먼저였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;지금은&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;왜 Controller와 Service를 나누는지&lt;/span&gt;&lt;br /&gt;&lt;span&gt;왜 DTO를 따로 만드는지&lt;/span&gt;&lt;br /&gt;&lt;span&gt;데이터가 어떤 흐름으로 이동하는지&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하나씩 생각하면서 개발하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 이제 다음 단계는 명확하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;지금 하드코딩되어 있는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;riskScore = 82
PHONE_NUMBER
ADDRESS&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 값들을 실제 이미지에서 찾아내는 것.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그러려면 먼저 이미지 안의 글자를 읽어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다음 편에서는 드디어 &lt;/span&gt;&lt;b&gt;&lt;span&gt;OCR&lt;/span&gt;&lt;/b&gt;&lt;span&gt;을 붙여본다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;가짜 분석 API를 진짜 분석기로 바꾸기 시작한다.&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>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/7</guid>
      <comments>https://nocklock.tistory.com/7#entry7comment</comments>
      <pubDate>Thu, 17 Sep 2026 22:12:22 +0900</pubDate>
    </item>
    <item>
      <title>사진 한 장은 생각보다 많은 것을 알고 있다.</title>
      <link>https://nocklock.tistory.com/9</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2026년 9월 16일 오후 07_18_01.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cw6wAT/dJMcagttIaa/Su8UieWPkyTi85k08MvHj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cw6wAT/dJMcagttIaa/Su8UieWPkyTi85k08MvHj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cw6wAT/dJMcagttIaa/Su8UieWPkyTi85k08MvHj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcw6wAT%2FdJMcagttIaa%2FSu8UieWPkyTi85k08MvHj1%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; alt=&quot;사진하나&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-filename=&quot;ChatGPT Image 2026년 9월 16일 오후 07_18_01.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;277&quot; data-start=&quot;265&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사진 한 장을 찍었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;277&quot; data-start=&quot;265&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;310&quot; data-start=&quot;279&quot; data-ke-size=&quot;size16&quot;&gt;그냥 커피 한 잔과 노트북이 놓여 있는 평범한 사진이다.&lt;/p&gt;
&lt;p data-end=&quot;350&quot; data-start=&quot;312&quot; data-ke-size=&quot;size16&quot;&gt;우리가 사진을 볼 때 가장 먼저 보는 것은 당연히 사진 속 장면이다.&lt;/p&gt;
&lt;p data-end=&quot;395&quot; data-start=&quot;352&quot; data-ke-size=&quot;size16&quot;&gt;그런데 개발자의 시선으로 사진을 바라보기 시작하면서 조금 다른 생각이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;446&quot; data-start=&quot;397&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사진에는 우리가 눈으로 보는 것 외에도 여러 종류의 정보가 함께 존재할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;494&quot; data-start=&quot;448&quot; data-ke-size=&quot;size16&quot;&gt;물론 사진 한 장만으로 누군가의 모든 개인정보를 알아낼 수 있다는 이야기는 아니다.&lt;/p&gt;
&lt;p data-end=&quot;533&quot; data-start=&quot;496&quot; data-ke-size=&quot;size16&quot;&gt;그 정도로 단순하지도 않고, 그렇게 이야기하는 것은 과장에 가깝다.&lt;/p&gt;
&lt;p data-end=&quot;592&quot; data-start=&quot;535&quot; data-ke-size=&quot;size16&quot;&gt;다만 사진을 만들고 공유하는 과정에서 우리가 의도하지 않았던 정보가 함께 포함될 가능성은 분명히 있다.&lt;/p&gt;
&lt;hr data-end=&quot;597&quot; data-start=&quot;594&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;624&quot; data-start=&quot;599&quot; data-section-id=&quot;6xuko1&quot; data-ke-size=&quot;size26&quot;&gt;사진 속에는 먼저 '보이는 정보'가 있다&lt;/h2&gt;
&lt;p data-end=&quot;651&quot; data-start=&quot;626&quot; data-ke-size=&quot;size16&quot;&gt;가장 단순한 것은 사진에 실제로 찍힌 정보다.&lt;/p&gt;
&lt;p data-end=&quot;677&quot; data-start=&quot;653&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 책상 사진을 찍었다고 생각해보자.&lt;/p&gt;
&lt;p data-end=&quot;705&quot; data-start=&quot;679&quot; data-ke-size=&quot;size16&quot;&gt;사진 한쪽에 이런 것들이 함께 찍힐 수도 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;767&quot; data-start=&quot;707&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;714&quot; data-start=&quot;707&quot; data-section-id=&quot;m8zd35&quot;&gt;택배 송장&lt;/li&gt;
&lt;li data-end=&quot;719&quot; data-start=&quot;715&quot; data-section-id=&quot;yhz351&quot;&gt;명함&lt;/li&gt;
&lt;li data-end=&quot;728&quot; data-start=&quot;720&quot; data-section-id=&quot;1jeierw&quot;&gt;회사 출입증&lt;/li&gt;
&lt;li data-end=&quot;734&quot; data-start=&quot;729&quot; data-section-id=&quot;2jxrak&quot;&gt;영수증&lt;/li&gt;
&lt;li data-end=&quot;743&quot; data-start=&quot;735&quot; data-section-id=&quot;zphtk&quot;&gt;모니터 화면&lt;/li&gt;
&lt;li data-end=&quot;748&quot; data-start=&quot;744&quot; data-section-id=&quot;yhywss&quot;&gt;문서&lt;/li&gt;
&lt;li data-end=&quot;767&quot; data-start=&quot;749&quot; data-section-id=&quot;xruip5&quot;&gt;전화번호나 이메일이 적힌 메모&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;803&quot; data-start=&quot;769&quot; data-ke-size=&quot;size16&quot;&gt;우리가 사진을 찍을 때는 보통 중심에 있는 피사체에 집중한다.&lt;/p&gt;
&lt;p data-end=&quot;842&quot; data-start=&quot;805&quot; data-ke-size=&quot;size16&quot;&gt;커피를 찍었다면 커피를 보고,&lt;br /&gt;노트북을 찍었다면 노트북을 본다.&lt;/p&gt;
&lt;p data-end=&quot;867&quot; data-start=&quot;844&quot; data-ke-size=&quot;size16&quot;&gt;하지만 컴퓨터는 사진 전체를 볼 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;923&quot; data-start=&quot;869&quot; data-ke-size=&quot;size16&quot;&gt;그리고 OCR, 즉 이미지 속 문자를 읽는 기술을 사용하면 사진 안의 텍스트를 추출할 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;934&quot; data-start=&quot;925&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 사진에&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;010-1234-5678&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;983&quot; data-start=&quot;963&quot; data-ke-size=&quot;size16&quot;&gt;같은 문자열이 선명하게 찍혀 있다면,&lt;/p&gt;
&lt;p data-end=&quot;1022&quot; data-start=&quot;985&quot; data-ke-size=&quot;size16&quot;&gt;프로그램은 그것이 전화번호와 비슷한 형태라는 것을 판단할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1076&quot; data-start=&quot;1024&quot; data-ke-size=&quot;size16&quot;&gt;이건 특별한 해킹 기술이라기보다는 우리가 이미 자주 사용하는 &lt;b&gt;문자 인식 기술&lt;/b&gt;에 가깝다.&lt;/p&gt;
&lt;hr data-end=&quot;1081&quot; data-start=&quot;1078&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1109&quot; data-start=&quot;1083&quot; data-section-id=&quot;1y8j83k&quot; data-ke-size=&quot;size26&quot;&gt;사진 파일 자체에도 정보가 들어갈 수 있다&lt;/h2&gt;
&lt;p data-end=&quot;1137&quot; data-start=&quot;1111&quot; data-ke-size=&quot;size16&quot;&gt;사진에서 눈에 보이는 정보만 있는 것도 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1185&quot; data-start=&quot;1139&quot; data-ke-size=&quot;size16&quot;&gt;디지털 사진 파일에는 경우에 따라 &lt;b&gt;EXIF&lt;/b&gt;라는 메타데이터가 포함될 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1199&quot; data-start=&quot;1187&quot; data-ke-size=&quot;size16&quot;&gt;EXIF는 쉽게 말하면&lt;/p&gt;
&lt;blockquote data-end=&quot;1230&quot; data-start=&quot;1201&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1230&quot; data-start=&quot;1203&quot; data-ke-size=&quot;size16&quot;&gt;이 사진이 어떻게 촬영되었는지 기록하는 부가 정보&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1244&quot; data-start=&quot;1232&quot; data-ke-size=&quot;size16&quot;&gt;정도로 생각하면 된다.&lt;/p&gt;
&lt;p data-end=&quot;1269&quot; data-start=&quot;1246&quot; data-ke-size=&quot;size16&quot;&gt;사진에 따라 이런 정보가 포함될 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;촬영 날짜와 시간
카메라 또는 스마트폰 모델
사진 크기
ISO
셔터 속도
조리개 값
GPS 위치 정보&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1356&quot; data-start=&quot;1341&quot; data-ke-size=&quot;size16&quot;&gt;여기서 중요한 부분이 있다.&lt;/p&gt;
&lt;p data-end=&quot;1389&quot; data-start=&quot;1358&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;모든 사진에 GPS 정보가 들어가는 것은 아니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1425&quot; data-start=&quot;1391&quot; data-ke-size=&quot;size16&quot;&gt;기기의 위치 설정이나 카메라 설정 등에 따라 달라질 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1498&quot; data-start=&quot;1427&quot; data-ke-size=&quot;size16&quot;&gt;또한 메신저나 SNS 같은 서비스를 통해 업로드되는 과정에서 사진이 다시 압축되거나 변환되면서 EXIF 정보가 제거되기도 한다.&lt;/p&gt;
&lt;p data-end=&quot;1502&quot; data-start=&quot;1500&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;blockquote data-end=&quot;1537&quot; data-start=&quot;1504&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1537&quot; data-start=&quot;1506&quot; data-ke-size=&quot;size16&quot;&gt;인터넷에 올라온 모든 사진에서 위치정보를 확인할 수 있다&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1555&quot; data-start=&quot;1539&quot; data-ke-size=&quot;size16&quot;&gt;라는 식으로 이해하면 틀리다.&lt;/p&gt;
&lt;p data-end=&quot;1589&quot; data-start=&quot;1557&quot; data-ke-size=&quot;size16&quot;&gt;내가 관심을 갖게 된 것은 그것보다 훨씬 단순한 부분이다.&lt;/p&gt;
&lt;p data-end=&quot;1653&quot; data-start=&quot;1591&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;우리가 사진을 하나의 이미지라고 생각하지만, 실제 파일에는 이미지 외의 데이터가 존재할 수도 있다는 것.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1658&quot; data-start=&quot;1655&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1681&quot; data-start=&quot;1660&quot; data-section-id=&quot;bnx8mb&quot; data-ke-size=&quot;size26&quot;&gt;각각은 별것 아닌 정보일 수 있다&lt;/h2&gt;
&lt;p data-end=&quot;1721&quot; data-start=&quot;1683&quot; data-ke-size=&quot;size16&quot;&gt;사진에 촬영 시간이 들어 있다고 해서 큰 문제가 생기는 것은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1753&quot; data-start=&quot;1723&quot; data-ke-size=&quot;size16&quot;&gt;카메라 모델을 안다고 해서 누군가를 특정할 수도 없다.&lt;/p&gt;
&lt;p data-end=&quot;1801&quot; data-start=&quot;1755&quot; data-ke-size=&quot;size16&quot;&gt;사진에 카페가 찍혀 있다고 해서 정확한 위치를 반드시 알아낼 수 있는 것도 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1825&quot; data-start=&quot;1803&quot; data-ke-size=&quot;size16&quot;&gt;각각을 따로 보면 대부분 평범한 정보다.&lt;/p&gt;
&lt;p data-end=&quot;1854&quot; data-start=&quot;1827&quot; data-ke-size=&quot;size16&quot;&gt;하지만 개인정보와 보안을 공부하면서 흥미로운 점은&lt;/p&gt;
&lt;p data-end=&quot;1901&quot; data-start=&quot;1856&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정보는 하나보다 여러 개가 결합됐을 때 의미가 달라질 수 있다는 것&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p data-end=&quot;1918&quot; data-start=&quot;1903&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 사진 안에 우연히&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;이름
회사명
이메일 주소
전화번호&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1967&quot; data-start=&quot;1952&quot; data-ke-size=&quot;size16&quot;&gt;가 동시에 노출되어 있다면,&lt;/p&gt;
&lt;p data-end=&quot;1999&quot; data-start=&quot;1969&quot; data-ke-size=&quot;size16&quot;&gt;각각 따로 존재할 때보다 개인정보 노출 위험은 커진다.&lt;/p&gt;
&lt;p data-end=&quot;2014&quot; data-start=&quot;2001&quot; data-ke-size=&quot;size16&quot;&gt;그래서 보안에서는 단순히&lt;/p&gt;
&lt;blockquote data-end=&quot;2032&quot; data-start=&quot;2016&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2032&quot; data-start=&quot;2018&quot; data-ke-size=&quot;size16&quot;&gt;개인정보가 있느냐, 없느냐&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2045&quot; data-start=&quot;2034&quot; data-ke-size=&quot;size16&quot;&gt;만 보는 것이 아니라&lt;/p&gt;
&lt;blockquote data-end=&quot;2089&quot; data-start=&quot;2047&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2089&quot; data-start=&quot;2049&quot; data-ke-size=&quot;size16&quot;&gt;어떤 정보가 얼마나 노출되어 있고&lt;br /&gt;서로 어떤 관계를 가지고 있는가&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2110&quot; data-start=&quot;2091&quot; data-ke-size=&quot;size16&quot;&gt;를 보는 것도 중요하다고 생각한다.&lt;/p&gt;
&lt;p data-end=&quot;2110&quot; data-start=&quot;2091&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;2681&quot; data-start=&quot;2658&quot; data-section-id=&quot;17zqkon&quot; data-ke-size=&quot;size26&quot;&gt;기술이 무서운 이유보다 더 중요한 것&lt;/h2&gt;
&lt;p data-end=&quot;2720&quot; data-start=&quot;2683&quot; data-ke-size=&quot;size16&quot;&gt;이 시리즈의 이름을&lt;br /&gt;&lt;b&gt;'기술이 조금 무섭다'&lt;/b&gt;라고 지었다.&lt;/p&gt;
&lt;p data-end=&quot;2763&quot; data-start=&quot;2722&quot; data-ke-size=&quot;size16&quot;&gt;그렇다고 기술이 위험하니 사용하지 말자는 이야기를 하고 싶은 것은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;2815&quot; data-start=&quot;2765&quot; data-ke-size=&quot;size16&quot;&gt;OCR도 유용한 기술이고,&lt;br /&gt;사진 메타데이터 역시 사진을 관리하는 데 유용하게 사용된다.&lt;/p&gt;
&lt;p data-end=&quot;2829&quot; data-start=&quot;2817&quot; data-ke-size=&quot;size16&quot;&gt;AI 역시 마찬가지다.&lt;/p&gt;
&lt;p data-end=&quot;2844&quot; data-start=&quot;2831&quot; data-ke-size=&quot;size16&quot;&gt;문제는 기술 그 자체보다&lt;/p&gt;
&lt;p data-end=&quot;2896&quot; data-start=&quot;2846&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그 기술이 어떤 정보를 처리하고 있는지 우리가 모르고 사용할 때&lt;/b&gt; 생긴다고 생각한다.&lt;/p&gt;
&lt;p data-end=&quot;2919&quot; data-start=&quot;2898&quot; data-ke-size=&quot;size16&quot;&gt;사진 한 장은 그냥 사진일 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;2928&quot; data-start=&quot;2921&quot; data-ke-size=&quot;size16&quot;&gt;하지만 때로는&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;사진 속 문자
+
파일의 메타데이터
+
사진 속 주변 정보&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2994&quot; data-start=&quot;2976&quot; data-ke-size=&quot;size16&quot;&gt;를 함께 가지고 있을 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;3035&quot; data-start=&quot;2996&quot; data-ke-size=&quot;size16&quot;&gt;그래서 사진을 공유하기 전에 잠깐 확인하는 습관 정도는 가져볼 만하다.&lt;/p&gt;
&lt;hr data-end=&quot;3040&quot; data-start=&quot;3037&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3064&quot; data-start=&quot;3042&quot; data-section-id=&quot;284o9l&quot; data-ke-size=&quot;size26&quot;&gt;사진은 기억이지만, 동시에 데이터다&lt;/h2&gt;
&lt;p data-end=&quot;3092&quot; data-start=&quot;3066&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 사진을 보면 그냥 기록이라고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;3115&quot; data-start=&quot;3094&quot; data-ke-size=&quot;size16&quot;&gt;여행 기록, 음식 기록, 일상의 기록.&lt;/p&gt;
&lt;p data-end=&quot;3151&quot; data-start=&quot;3117&quot; data-ke-size=&quot;size16&quot;&gt;그런데 개발자로 다시 공부하면서 조금 다르게 보이기 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;3167&quot; data-start=&quot;3153&quot; data-ke-size=&quot;size16&quot;&gt;사진은 이미지이기도 하지만&lt;/p&gt;
&lt;p data-end=&quot;3190&quot; data-start=&quot;3169&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하나의 데이터 파일이기도 하다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3237&quot; data-start=&quot;3192&quot; data-ke-size=&quot;size16&quot;&gt;그리고 데이터에는 때때로&lt;br /&gt;우리가 의도하지 않았던 정보가 함께 들어갈 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;3278&quot; data-start=&quot;3239&quot; data-ke-size=&quot;size16&quot;&gt;그 사실을 알고 있는 것과 모르고 있는 것은 꽤 큰 차이라고 생각한다.&lt;/p&gt;
&lt;p data-end=&quot;3300&quot; data-start=&quot;3280&quot; data-ke-size=&quot;size16&quot;&gt;그래서 나는 기술을 무서워하기보다는,&lt;/p&gt;
&lt;p data-end=&quot;3338&quot; data-start=&quot;3302&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기술이 무엇을 할 수 있는지 이해하는 개발자가 되고 싶다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3349&quot; data-start=&quot;3340&quot; data-ke-size=&quot;size16&quot;&gt;그리고 가능하다면&lt;/p&gt;
&lt;p data-end=&quot;3403&quot; data-start=&quot;3351&quot; data-ke-size=&quot;size16&quot;&gt;기술 때문에 생기는 작은 위험을&lt;br /&gt;기술로 한 번 더 확인할 수 있는 도구를 만들어보고 싶다.&lt;/p&gt;
&lt;p data-end=&quot;3442&quot; data-start=&quot;3405&quot; data-ke-size=&quot;size16&quot;&gt;Security Lens를 만들기 시작한 이유도 결국 그곳에 있다.&lt;/p&gt;
&lt;hr data-end=&quot;3447&quot; data-start=&quot;3444&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;blockquote data-end=&quot;3527&quot; data-start=&quot;3449&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;3527&quot; data-start=&quot;3451&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사진 한 장이 모든 것을 알고 있는 것은 아니다.&lt;/b&gt;&lt;br /&gt;다만 우리가 생각했던 것보다 조금 더 많은 정보를 가지고 있을 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>기술이 조금 무섭다</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/9</guid>
      <comments>https://nocklock.tistory.com/9#entry9comment</comments>
      <pubDate>Thu, 17 Sep 2026 14:21:29 +0900</pubDate>
    </item>
    <item>
      <title>Spring Boot 실행 버튼을 누르면 실제로 무슨 일이 일어날까? | RE:개발자 #4</title>
      <link>https://nocklock.tistory.com/6</link>
      <description>&lt;h2 data-end=&quot;297&quot; data-start=&quot;259&quot; data-ke-size=&quot;size26&quot;&gt;Spring Boot, 실행 버튼을 누르면무슨 일이 일어날까?&lt;/h2&gt;
&lt;p data-end=&quot;322&quot; data-start=&quot;299&quot; data-ke-size=&quot;size16&quot;&gt;개발하면서 정말 많이 눌렀던 버튼이 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;springboot.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwMKhv/dJMcafnTsH7/D7XHFCeWgk5w6EsyW9IKdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwMKhv/dJMcafnTsH7/D7XHFCeWgk5w6EsyW9IKdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwMKhv/dJMcafnTsH7/D7XHFCeWgk5w6EsyW9IKdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwMKhv%2FdJMcafnTsH7%2FD7XHFCeWgk5w6EsyW9IKdK%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;1672&quot; height=&quot;941&quot; data-filename=&quot;springboot.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;344&quot; data-start=&quot;324&quot; data-ke-size=&quot;size16&quot;&gt;IntelliJ의 초록색 실행 버튼.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public static void main(String[] args) {
    SpringApplication.run(SecurityLensApplication.class, args);
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;485&quot; data-start=&quot;466&quot; data-ke-size=&quot;size16&quot;&gt;회사에서도 수도 없이 봤던 코드다.&lt;/p&gt;
&lt;p data-end=&quot;513&quot; data-start=&quot;487&quot; data-ke-size=&quot;size16&quot;&gt;SpringApplication.run().&lt;/p&gt;
&lt;p data-end=&quot;531&quot; data-start=&quot;515&quot; data-ke-size=&quot;size16&quot;&gt;이걸 실행하면 서버가 켜지고,&lt;/p&gt;
&lt;p data-end=&quot;578&quot; data-start=&quot;533&quot; data-ke-size=&quot;size16&quot;&gt;브라우저에서 localhost:8080으로 접속하면 내가 만든 화면이 나온다.&lt;/p&gt;
&lt;p data-end=&quot;598&quot; data-start=&quot;580&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 사실 여기까지만 알았다.&lt;/p&gt;
&lt;blockquote data-end=&quot;628&quot; data-start=&quot;600&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;628&quot; data-start=&quot;602&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;Spring Boot 실행하는 코드.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;661&quot; data-start=&quot;630&quot; data-ke-size=&quot;size16&quot;&gt;그런데 Gradle을 다시 공부하다 보니 또 궁금해졌다.&lt;/p&gt;
&lt;p data-end=&quot;697&quot; data-start=&quot;663&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실행 버튼을 누른 뒤에 대체 무슨 일이 일어나는 걸까?&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;702&quot; data-start=&quot;699&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;727&quot; data-start=&quot;704&quot; data-ke-size=&quot;size26&quot;&gt;시작은 결국 Java main()이다&lt;/h2&gt;
&lt;p data-end=&quot;762&quot; data-start=&quot;729&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot 프로젝트도 결국 Java 프로그램이다.&lt;/p&gt;
&lt;p data-end=&quot;781&quot; data-start=&quot;764&quot; data-ke-size=&quot;size16&quot;&gt;그래서 시작점은 특별하지 않다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;public static void main(String[] args)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;871&quot; data-start=&quot;835&quot; data-ke-size=&quot;size16&quot;&gt;Java를 처음 배울 때 봤던 바로 그 main() 메서드다.&lt;/p&gt;
&lt;p data-end=&quot;886&quot; data-start=&quot;873&quot; data-ke-size=&quot;size16&quot;&gt;차이가 있다면 그 안에서&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;SpringApplication.run(...)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;940&quot; data-start=&quot;928&quot; data-ke-size=&quot;size16&quot;&gt;을 실행한다는 것이다.&lt;/p&gt;
&lt;p data-end=&quot;970&quot; data-start=&quot;942&quot; data-ke-size=&quot;size16&quot;&gt;나는 예전에는 이 한 줄을 거의 주문처럼 생각했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;SpringApplication.run();&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote data-end=&quot;1029&quot; data-start=&quot;1010&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1029&quot; data-start=&quot;1012&quot; data-ke-size=&quot;size16&quot;&gt;적으면 Spring이 실행된다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1042&quot; data-start=&quot;1031&quot; data-ke-size=&quot;size16&quot;&gt;틀린 말은 아니지만,&lt;/p&gt;
&lt;p data-end=&quot;1078&quot; data-start=&quot;1044&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 그 뒤에서 어떤 일이 일어나는지 조금 더 들여다봤다.&lt;/p&gt;
&lt;hr data-end=&quot;1083&quot; data-start=&quot;1080&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1119&quot; data-start=&quot;1085&quot;&gt;1. SpringApplication.run()이 실행된다&lt;/h1&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;SpringApplication.run(SecurityLensApplication.class, args);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1227&quot; data-start=&quot;1194&quot; data-ke-size=&quot;size16&quot;&gt;여기서 Spring Boot가 애플리케이션 실행을 시작한다.&lt;/p&gt;
&lt;p data-end=&quot;1239&quot; data-start=&quot;1229&quot; data-ke-size=&quot;size16&quot;&gt;설정 정보를 읽고,&lt;/p&gt;
&lt;p data-end=&quot;1265&quot; data-start=&quot;1241&quot; data-ke-size=&quot;size16&quot;&gt;현재 애플리케이션이 어떤 형태인지 판단하고,&lt;/p&gt;
&lt;p data-end=&quot;1288&quot; data-start=&quot;1267&quot; data-ke-size=&quot;size16&quot;&gt;Spring이 관리할 환경을 준비한다.&lt;/p&gt;
&lt;p data-end=&quot;1310&quot; data-start=&quot;1290&quot; data-ke-size=&quot;size16&quot;&gt;그리고 중요한 것이 하나 만들어진다.&lt;/p&gt;
&lt;p data-end=&quot;1339&quot; data-start=&quot;1312&quot; data-ke-size=&quot;size16&quot;&gt;바로 &lt;b&gt;ApplicationContext&lt;/b&gt;다.&lt;/p&gt;
&lt;hr data-end=&quot;1344&quot; data-start=&quot;1341&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1376&quot; data-start=&quot;1346&quot;&gt;2. ApplicationContext가 만들어진다&lt;/h1&gt;
&lt;p data-end=&quot;1407&quot; data-start=&quot;1378&quot; data-ke-size=&quot;size16&quot;&gt;Spring을 공부하면 굉장히 자주 등장하는 단어다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;ApplicationContext&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1452&quot; data-start=&quot;1441&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 이것도 그냥&lt;/p&gt;
&lt;p data-end=&quot;1472&quot; data-start=&quot;1454&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;Spring 컨테이너.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1482&quot; data-start=&quot;1474&quot; data-ke-size=&quot;size16&quot;&gt;정도로 외웠다.&lt;/p&gt;
&lt;p data-end=&quot;1496&quot; data-start=&quot;1484&quot; data-ke-size=&quot;size16&quot;&gt;지금 다시 이해해보면,&lt;/p&gt;
&lt;p data-end=&quot;1539&quot; data-start=&quot;1498&quot; data-ke-size=&quot;size16&quot;&gt;Spring이 객체들을 생성하고 관리하기 위한 공간이라고 생각하면 편했다.&lt;/p&gt;
&lt;p data-end=&quot;1563&quot; data-start=&quot;1541&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 우리가 이런 클래스를 만든다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;@Service
public class ImageAnalysisService {

}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1657&quot; data-start=&quot;1626&quot; data-ke-size=&quot;size16&quot;&gt;일반 Java라면 필요할 때 직접 객체를 만들어야 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;ImageAnalysisService service
        = new ImageAnalysisService();&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1771&quot; data-start=&quot;1739&quot; data-ke-size=&quot;size16&quot;&gt;그런데 Spring에서는 보통 직접 이렇게 만들지 않는다.&lt;/p&gt;
&lt;p data-end=&quot;1795&quot; data-start=&quot;1773&quot; data-ke-size=&quot;size16&quot;&gt;Spring이 객체를 생성하고 관리한다.&lt;/p&gt;
&lt;p data-end=&quot;1826&quot; data-start=&quot;1797&quot; data-ke-size=&quot;size16&quot;&gt;그 객체를 우리가 흔히 &lt;b&gt;Bean&lt;/b&gt;이라고 부른다.&lt;/p&gt;
&lt;p data-end=&quot;1830&quot; data-start=&quot;1828&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;ApplicationContext
        &amp;darr;
Spring Bean 관리
        &amp;darr;
Controller
Service
Repository
...&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1946&quot; data-start=&quot;1933&quot; data-ke-size=&quot;size16&quot;&gt;이런 구조라고 이해했다.&lt;/p&gt;
&lt;hr data-end=&quot;1951&quot; data-start=&quot;1948&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;1985&quot; data-start=&quot;1953&quot;&gt;3. @SpringBootApplication을 찾는다&lt;/h1&gt;
&lt;p data-end=&quot;2029&quot; data-start=&quot;1987&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot 프로젝트의 메인 클래스를 보면 보통 이런 코드가 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;@SpringBootApplication
public class SecurityLensApplication {

    public static void main(String[] args) {
        SpringApplication.run(
                SecurityLensApplication.class,
                args
        );
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2280&quot; data-start=&quot;2270&quot; data-ke-size=&quot;size16&quot;&gt;여기서 중요한 것이&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;aspectj&quot;&gt;&lt;code&gt;@SpringBootApplication&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2321&quot; data-start=&quot;2318&quot; data-ke-size=&quot;size16&quot;&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;2330&quot; data-start=&quot;2323&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 그냥&lt;/p&gt;
&lt;blockquote data-end=&quot;2369&quot; data-start=&quot;2332&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2369&quot; data-start=&quot;2334&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;Spring Boot 프로젝트니까 붙이는 어노테이션.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2380&quot; data-start=&quot;2371&quot; data-ke-size=&quot;size16&quot;&gt;정도로 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;2411&quot; data-start=&quot;2382&quot; data-ke-size=&quot;size16&quot;&gt;그런데 실제로는 여러 역할을 합쳐놓은 어노테이션이다.&lt;/p&gt;
&lt;p data-end=&quot;2418&quot; data-start=&quot;2413&quot; data-ke-size=&quot;size16&quot;&gt;대표적으로&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;@Configuration
@EnableAutoConfiguration
@ComponentScan&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2502&quot; data-start=&quot;2488&quot; data-ke-size=&quot;size16&quot;&gt;의 기능이 포함되어 있다.&lt;/p&gt;
&lt;p data-end=&quot;2547&quot; data-start=&quot;2504&quot; data-ke-size=&quot;size16&quot;&gt;이 중 내가 먼저 이해해야겠다고 생각한 건 ComponentScan이었다.&lt;/p&gt;
&lt;hr data-end=&quot;2552&quot; data-start=&quot;2549&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2579&quot; data-start=&quot;2554&quot;&gt;4. Spring이 내 클래스를 찾아다닌다&lt;/h1&gt;
&lt;p data-end=&quot;2600&quot; data-start=&quot;2581&quot; data-ke-size=&quot;size16&quot;&gt;내 프로젝트에는 이런 것들이 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;@RestController
@Service
@Repository
@Component&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2716&quot; data-start=&quot;2663&quot; data-ke-size=&quot;size16&quot;&gt;Spring은 Component Scan을 통해 이런 클래스들을 찾아서 관리 대상으로 등록한다.&lt;/p&gt;
&lt;p data-end=&quot;2723&quot; data-start=&quot;2718&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;@RestController
public class AnalysisController {

}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2794&quot; data-start=&quot;2791&quot; data-ke-size=&quot;size16&quot;&gt;그리고&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;@Service
public class ImageAnalysisService {

}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2863&quot; data-start=&quot;2857&quot; data-ke-size=&quot;size16&quot;&gt;가 있다면,&lt;/p&gt;
&lt;p data-end=&quot;2896&quot; data-start=&quot;2865&quot; data-ke-size=&quot;size16&quot;&gt;Spring이 해당 클래스들을 발견하고 객체를 생성한다.&lt;/p&gt;
&lt;p data-end=&quot;2907&quot; data-start=&quot;2898&quot; data-ke-size=&quot;size16&quot;&gt;결국 우리가 매번&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;haxe&quot;&gt;&lt;code&gt;new AnalysisController();
new ImageAnalysisService();&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2997&quot; data-start=&quot;2976&quot; data-ke-size=&quot;size16&quot;&gt;를 하지 않아도 되는 이유 중 하나다.&lt;/p&gt;
&lt;p data-end=&quot;3027&quot; data-start=&quot;2999&quot; data-ke-size=&quot;size16&quot;&gt;그리고 여기서 예전에 외웠던 단어가 다시 등장한다.&lt;/p&gt;
&lt;p data-end=&quot;3037&quot; data-start=&quot;3029&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;IoC.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;3042&quot; data-start=&quot;3039&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3062&quot; data-start=&quot;3044&quot;&gt;IoC를 이제야 조금 이해했다&lt;/h1&gt;
&lt;p data-end=&quot;3087&quot; data-start=&quot;3064&quot; data-ke-size=&quot;size16&quot;&gt;면접 공부를 하면 이런 질문을 많이 본다.&lt;/p&gt;
&lt;blockquote data-end=&quot;3100&quot; data-start=&quot;3089&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;3100&quot; data-start=&quot;3091&quot; data-ke-size=&quot;size16&quot;&gt;IoC가 뭔가요?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;3117&quot; data-start=&quot;3102&quot; data-ke-size=&quot;size16&quot;&gt;예전의 나는 이렇게 외웠다.&lt;/p&gt;
&lt;blockquote data-end=&quot;3135&quot; data-start=&quot;3119&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;3135&quot; data-start=&quot;3121&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;제어의 역전입니다.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;3144&quot; data-start=&quot;3137&quot; data-ke-size=&quot;size16&quot;&gt;맞는 말이다.&lt;/p&gt;
&lt;p data-end=&quot;3169&quot; data-start=&quot;3146&quot; data-ke-size=&quot;size16&quot;&gt;그런데 사실 그 뒤를 설명하기가 애매했다.&lt;/p&gt;
&lt;p data-end=&quot;3187&quot; data-start=&quot;3171&quot; data-ke-size=&quot;size16&quot;&gt;지금은 이렇게 이해하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;3216&quot; data-start=&quot;3189&quot; data-ke-size=&quot;size16&quot;&gt;일반 Java 프로그램에서는 내가 객체를 만든다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;ImageAnalysisService service
        = new ImageAnalysisService();&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3322&quot; data-start=&quot;3298&quot; data-ke-size=&quot;size16&quot;&gt;즉 객체 생성에 대한 제어권이 나에게 있다.&lt;/p&gt;
&lt;p data-end=&quot;3354&quot; data-start=&quot;3324&quot; data-ke-size=&quot;size16&quot;&gt;Spring에서는 객체 생성을 Spring에게 맡긴다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;@Service
public class ImageAnalysisService {
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3442&quot; data-start=&quot;3416&quot; data-ke-size=&quot;size16&quot;&gt;그러면 Spring이 객체를 생성하고 관리한다.&lt;/p&gt;
&lt;p data-end=&quot;3488&quot; data-start=&quot;3444&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;객체를 만들고 관리하는 제어권이 개발자에게서 Spring으로 넘어간 것.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3538&quot; data-start=&quot;3490&quot; data-ke-size=&quot;size16&quot;&gt;그래서 &lt;b&gt;Inversion of Control&lt;/b&gt;, 제어의 역전이라고 부르는 것이다.&lt;/p&gt;
&lt;p data-end=&quot;3562&quot; data-start=&quot;3540&quot; data-ke-size=&quot;size16&quot;&gt;단어만 외웠을 때보다 훨씬 이해가 됐다.&lt;/p&gt;
&lt;hr data-end=&quot;3567&quot; data-start=&quot;3564&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3598&quot; data-start=&quot;3569&quot;&gt;5. Auto Configuration이 동작한다&lt;/h1&gt;
&lt;p data-end=&quot;3630&quot; data-start=&quot;3600&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot가 편한 가장 큰 이유 중 하나다.&lt;/p&gt;
&lt;p data-end=&quot;3642&quot; data-start=&quot;3632&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;자동 설정.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3652&quot; data-start=&quot;3644&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 내가&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;clean&quot;&gt;&lt;code&gt;implementation 'org.springframework.boot:spring-boot-starter-web'&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3741&quot; data-start=&quot;3735&quot; data-ke-size=&quot;size16&quot;&gt;을 추가하면&lt;/p&gt;
&lt;p data-end=&quot;3755&quot; data-start=&quot;3743&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot는&lt;/p&gt;
&lt;blockquote data-end=&quot;3777&quot; data-start=&quot;3757&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;3777&quot; data-start=&quot;3759&quot; data-ke-size=&quot;size16&quot;&gt;웹 프로젝트를 만들려고 하는구나.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;3806&quot; data-start=&quot;3779&quot; data-ke-size=&quot;size16&quot;&gt;라고 판단하고 필요한 설정들을 자동으로 구성한다.&lt;/p&gt;
&lt;p data-end=&quot;3866&quot; data-start=&quot;3808&quot; data-ke-size=&quot;size16&quot;&gt;과거 Spring에서는 개발자가 직접 설정해야 했던 많은 부분을 Spring Boot가 대신 처리해준다.&lt;/p&gt;
&lt;p data-end=&quot;3895&quot; data-start=&quot;3868&quot; data-ke-size=&quot;size16&quot;&gt;여기서 3편에서 공부했던 Gradle과 연결된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;build.gradle
      &amp;darr;
starter-web 추가
      &amp;darr;
관련 라이브러리 로딩
      &amp;darr;
Spring Boot Auto Configuration
      &amp;darr;
웹 애플리케이션 환경 구성&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4067&quot; data-start=&quot;4028&quot; data-ke-size=&quot;size16&quot;&gt;Gradle과 Spring Boot가 완전히 따로 노는 것이 아니었다.&lt;/p&gt;
&lt;p data-end=&quot;4083&quot; data-start=&quot;4069&quot; data-ke-size=&quot;size16&quot;&gt;조금씩 연결되기 시작했다.&lt;/p&gt;
&lt;hr data-end=&quot;4088&quot; data-start=&quot;4085&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;4108&quot; data-start=&quot;4090&quot;&gt;6. 내장 웹 서버가 실행된다&lt;/h1&gt;
&lt;p data-end=&quot;4144&quot; data-start=&quot;4110&quot; data-ke-size=&quot;size16&quot;&gt;그리고 Spring Boot 웹 프로젝트라면 서버도 필요하다.&lt;/p&gt;
&lt;p data-end=&quot;4198&quot; data-start=&quot;4146&quot; data-ke-size=&quot;size16&quot;&gt;예전 Spring MVC 프로젝트에서는 Tomcat을 별도로 설치해서 사용하는 경우가 많았다.&lt;/p&gt;
&lt;p data-end=&quot;4235&quot; data-start=&quot;4200&quot; data-ke-size=&quot;size16&quot;&gt;나 역시 회사에서 Tomcat 설정을 직접 만졌던 기억이 있다.&lt;/p&gt;
&lt;p data-end=&quot;4292&quot; data-start=&quot;4237&quot; data-ke-size=&quot;size16&quot;&gt;그런데 Spring Boot에서는 기본적으로 웹 서버를 애플리케이션 안에 포함해서 사용할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;4309&quot; data-start=&quot;4294&quot; data-ke-size=&quot;size16&quot;&gt;대표적으로 Tomcat이다.&lt;/p&gt;
&lt;p data-end=&quot;4342&quot; data-start=&quot;4311&quot; data-ke-size=&quot;size16&quot;&gt;그래서 프로젝트를 실행하면 콘솔에 이런 메시지가 보인다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Tomcat started on port 8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4406&quot; data-start=&quot;4385&quot; data-ke-size=&quot;size16&quot;&gt;그동안 별 생각 없이 지나쳤던 로그다.&lt;/p&gt;
&lt;p data-end=&quot;4423&quot; data-start=&quot;4408&quot; data-ke-size=&quot;size16&quot;&gt;하지만 이 시점에서야 비로소&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;localhost:8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4473&quot; data-start=&quot;4453&quot; data-ke-size=&quot;size16&quot;&gt;으로 요청을 받을 준비가 된 것이다.&lt;/p&gt;
&lt;hr data-end=&quot;4478&quot; data-start=&quot;4475&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;4511&quot; data-start=&quot;4480&quot;&gt;그런데 요청은 Controller로 바로 가는 걸까?&lt;/h1&gt;
&lt;p data-end=&quot;4528&quot; data-start=&quot;4513&quot; data-ke-size=&quot;size16&quot;&gt;여기서 또 하나 궁금해졌다.&lt;/p&gt;
&lt;p data-end=&quot;4536&quot; data-start=&quot;4530&quot; data-ke-size=&quot;size16&quot;&gt;브라우저에서&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;GET /api/analyze&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4602&quot; data-start=&quot;4568&quot; data-ke-size=&quot;size16&quot;&gt;같은 요청을 보내면 바로 Controller가 실행되는 걸까?&lt;/p&gt;
&lt;p data-end=&quot;4613&quot; data-start=&quot;4604&quot; data-ke-size=&quot;size16&quot;&gt;정확히는 아니다.&lt;/p&gt;
&lt;p data-end=&quot;4651&quot; data-start=&quot;4615&quot; data-ke-size=&quot;size16&quot;&gt;Spring MVC에는 요청을 먼저 받아주는 중요한 객체가 있다.&lt;/p&gt;
&lt;p data-end=&quot;4655&quot; data-start=&quot;4653&quot; data-ke-size=&quot;size16&quot;&gt;바로&lt;/p&gt;
&lt;p data-end=&quot;4681&quot; data-start=&quot;4657&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DispatcherServlet&lt;/b&gt;이다.&lt;/p&gt;
&lt;hr data-end=&quot;4686&quot; data-start=&quot;4683&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;4719&quot; data-start=&quot;4688&quot;&gt;7. DispatcherServlet이 요청을 받는다&lt;/h1&gt;
&lt;p data-end=&quot;4771&quot; data-start=&quot;4721&quot; data-ke-size=&quot;size16&quot;&gt;Spring MVC 구조에서 DispatcherServlet은 굉장히 중요한 역할을 한다.&lt;/p&gt;
&lt;p data-end=&quot;4813&quot; data-start=&quot;4773&quot; data-ke-size=&quot;size16&quot;&gt;웹 요청이 들어오면 먼저 DispatcherServlet이 요청을 받고,&lt;/p&gt;
&lt;p data-end=&quot;4844&quot; data-start=&quot;4815&quot; data-ke-size=&quot;size16&quot;&gt;어떤 Controller가 처리해야 하는지 찾아간다.&lt;/p&gt;
&lt;p data-end=&quot;4851&quot; data-start=&quot;4846&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;@RestController
@RequestMapping(&quot;/api&quot;)
public class AnalysisController {

    @PostMapping(&quot;/analyze&quot;)
    public AnalysisResponse analyze() {

    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5025&quot; data-start=&quot;5019&quot; data-ke-size=&quot;size16&quot;&gt;가 있다면,&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;POST /api/analyze&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5098&quot; data-start=&quot;5058&quot; data-ke-size=&quot;size16&quot;&gt;요청이 들어왔을 때 적절한 Controller 메서드를 찾아 연결해준다.&lt;/p&gt;
&lt;p data-end=&quot;5116&quot; data-start=&quot;5100&quot; data-ke-size=&quot;size16&quot;&gt;간단하게 보면 이런 흐름이다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Browser
   &amp;darr;
Tomcat
   &amp;darr;
DispatcherServlet
   &amp;darr;
Controller
   &amp;darr;
Service
   &amp;darr;
Repository&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5240&quot; data-start=&quot;5219&quot; data-ke-size=&quot;size16&quot;&gt;그리고 결과는 반대 방향으로 돌아간다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Repository
   &amp;darr;
Service
   &amp;darr;
Controller
   &amp;darr;
HTTP Response
   &amp;darr;
Browser&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5369&quot; data-start=&quot;5327&quot; data-ke-size=&quot;size16&quot;&gt;내가 회사에서 만들었던 MVC 구조도 결국 이 흐름 위에서 동작하고 있었다.&lt;/p&gt;
&lt;hr data-end=&quot;5374&quot; data-start=&quot;5371&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;5406&quot; data-start=&quot;5376&quot;&gt;결국 실행 버튼 하나 뒤에 이렇게 많은 일이 있었다&lt;/h1&gt;
&lt;p data-end=&quot;5415&quot; data-start=&quot;5408&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 그냥&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;▶ Run&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5440&quot; data-start=&quot;5436&quot; data-ke-size=&quot;size16&quot;&gt;이었다.&lt;/p&gt;
&lt;p data-end=&quot;5472&quot; data-start=&quot;5442&quot; data-ke-size=&quot;size16&quot;&gt;그런데 조금만 안쪽을 들여다보니 대략 이런 흐름이었다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;main()
  &amp;darr;
SpringApplication.run()
  &amp;darr;
ApplicationContext 생성
  &amp;darr;
Component Scan
  &amp;darr;
Bean 생성 및 관리
  &amp;darr;
Auto Configuration
  &amp;darr;
내장 Tomcat 실행
  &amp;darr;
DispatcherServlet 준비
  &amp;darr;
HTTP 요청 처리&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5699&quot; data-start=&quot;5664&quot; data-ke-size=&quot;size16&quot;&gt;물론 실제 Spring Boot 내부는 이것보다 훨씬 복잡하다.&lt;/p&gt;
&lt;p data-end=&quot;5712&quot; data-start=&quot;5701&quot; data-ke-size=&quot;size16&quot;&gt;그래도 적어도 이제는&lt;/p&gt;
&lt;blockquote data-end=&quot;5745&quot; data-start=&quot;5714&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;5745&quot; data-start=&quot;5716&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;Spring Boot가 어떻게 실행되나요?&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;5753&quot; data-start=&quot;5747&quot; data-ke-size=&quot;size16&quot;&gt;라는 질문에&lt;/p&gt;
&lt;p data-end=&quot;5808&quot; data-start=&quot;5755&quot; data-ke-size=&quot;size16&quot;&gt;SpringApplication.run()이라고만 대답하고 끝내지는 않을 수 있을 것 같다.&lt;/p&gt;
&lt;hr data-end=&quot;5813&quot; data-start=&quot;5810&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;5840&quot; data-start=&quot;5815&quot;&gt;이번에도 Claude Code에게 물어봤다&lt;/h1&gt;
&lt;p data-end=&quot;5880&quot; data-start=&quot;5842&quot; data-ke-size=&quot;size16&quot;&gt;요즘 프로젝트를 만들면서 Claude Code를 같이 사용하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;5890&quot; data-start=&quot;5882&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 단순히&lt;/p&gt;
&lt;blockquote data-end=&quot;5916&quot; data-start=&quot;5892&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;5916&quot; data-start=&quot;5894&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot 실행 과정 알려줘.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;5935&quot; data-start=&quot;5918&quot; data-ke-size=&quot;size16&quot;&gt;라고 묻는 데서 끝내지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;5949&quot; data-start=&quot;5937&quot; data-ke-size=&quot;size16&quot;&gt;내가 만든 프로젝트에서&lt;/p&gt;
&lt;blockquote data-end=&quot;6035&quot; data-start=&quot;5951&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;6035&quot; data-start=&quot;5953&quot; data-ke-size=&quot;size16&quot;&gt;현재 프로젝트를 기준으로 Spring Boot 실행 이후 어떤 Bean들이 만들어지고 Controller 요청까지 어떤 구조로 연결되는지 설명해줘.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;6059&quot; data-start=&quot;6037&quot; data-ke-size=&quot;size16&quot;&gt;처럼 실제 프로젝트를 기준으로 물어봤다.&lt;/p&gt;
&lt;p data-end=&quot;6095&quot; data-start=&quot;6061&quot; data-ke-size=&quot;size16&quot;&gt;그랬더니 책에서 보는 추상적인 설명보다 훨씬 이해하기 쉬웠다.&lt;/p&gt;
&lt;p data-end=&quot;6148&quot; data-start=&quot;6097&quot; data-ke-size=&quot;size16&quot;&gt;내 Controller, Service, DTO가 실제 설명 속에 등장하기 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;6178&quot; data-start=&quot;6150&quot; data-ke-size=&quot;size16&quot;&gt;AI를 공부에 사용하는 방법도 조금씩 바뀌고 있다.&lt;/p&gt;
&lt;p data-end=&quot;6219&quot; data-start=&quot;6180&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;답을 대신 얻는 도구에서, 내가 작성한 코드를 이해하는 도구로.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;6244&quot; data-start=&quot;6221&quot; data-ke-size=&quot;size16&quot;&gt;이 방식이 지금의 나에게는 꽤 잘 맞는다.&lt;/p&gt;
&lt;hr data-end=&quot;6249&quot; data-start=&quot;6246&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;6275&quot; data-start=&quot;6251&quot;&gt;예전에 외웠던 단어들이 연결되기 시작했다&lt;/h1&gt;
&lt;p data-end=&quot;6319&quot; data-start=&quot;6277&quot; data-ke-size=&quot;size16&quot;&gt;이번에 Spring Boot 실행 과정을 다시 보면서 재미있는 점이 있었다.&lt;/p&gt;
&lt;p data-end=&quot;6358&quot; data-start=&quot;6321&quot; data-ke-size=&quot;size16&quot;&gt;예전에 따로따로 외웠던 단어들이 하나의 흐름으로 연결되기 시작했다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;Gradle
Dependency
Spring Boot
Bean
ApplicationContext
IoC
Component Scan
Tomcat
DispatcherServlet
MVC&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6494&quot; data-start=&quot;6475&quot; data-ke-size=&quot;size16&quot;&gt;회사에서는 전부 사용했던 것들이다.&lt;/p&gt;
&lt;p data-end=&quot;6519&quot; data-start=&quot;6496&quot; data-ke-size=&quot;size16&quot;&gt;그런데 당시에는 각각을 따로 알고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;6539&quot; data-start=&quot;6521&quot; data-ke-size=&quot;size16&quot;&gt;지금 다시 공부하면서 느끼는 건,&lt;/p&gt;
&lt;p data-end=&quot;6574&quot; data-start=&quot;6541&quot; data-ke-size=&quot;size16&quot;&gt;개발 공부에서 중요한 건 용어를 얼마나 많이 아느냐가 아니라&lt;/p&gt;
&lt;p data-end=&quot;6616&quot; data-start=&quot;6576&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그 기술들이 어떻게 연결되어 있는지를 이해하는 것&lt;/b&gt;인지도 모르겠다.&lt;/p&gt;
&lt;hr data-end=&quot;6621&quot; data-start=&quot;6618&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;6632&quot; data-start=&quot;6623&quot; data-ke-size=&quot;size26&quot;&gt;RE:개발자&lt;/h2&gt;
&lt;p data-end=&quot;6673&quot; data-start=&quot;6634&quot; data-ke-size=&quot;size16&quot;&gt;한 번 개발자였던 사람이&lt;br /&gt;다시 개발자가 되어가는 과정을 기록합니다.&lt;/p&gt;
&lt;p data-end=&quot;6702&quot; data-start=&quot;6675&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 실행 버튼 하나를 조금 깊게 들여다봤다.&lt;/p&gt;
&lt;p data-end=&quot;6722&quot; data-start=&quot;6704&quot; data-ke-size=&quot;size16&quot;&gt;그리고 다음에는 그 실행된 서버에&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;http://localhost:8080&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;6772&quot; data-start=&quot;6759&quot; data-ke-size=&quot;size16&quot;&gt;으로 요청을 보냈을 때,&lt;/p&gt;
&lt;p data-end=&quot;6813&quot; data-start=&quot;6774&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;HTTP 요청이 실제로 어떻게 Controller까지 도착하는지&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;6834&quot; data-start=&quot;6815&quot; data-ke-size=&quot;size16&quot;&gt;조금 더 자세히 따라가보려고 한다.&lt;/p&gt;</description>
      <category>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/6</guid>
      <comments>https://nocklock.tistory.com/6#entry6comment</comments>
      <pubDate>Thu, 17 Sep 2026 10:26:20 +0900</pubDate>
    </item>
    <item>
      <title>Gradle이란 뭘까? 매일 쓰면서도 제대로 몰랐다 | RE:개발자 #3</title>
      <link>https://nocklock.tistory.com/5</link>
      <description>&lt;h2 data-end=&quot;385&quot; data-start=&quot;358&quot; data-ke-size=&quot;size26&quot;&gt;Gradle, 나는 왜 이걸 쓰고 있었을까?&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;gradle.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZLD0W/dJMcac5EZvE/9aHG5kAcw1Nh0zkj3FPgBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZLD0W/dJMcac5EZvE/9aHG5kAcw1Nh0zkj3FPgBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZLD0W/dJMcac5EZvE/9aHG5kAcw1Nh0zkj3FPgBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZLD0W%2FdJMcac5EZvE%2F9aHG5kAcw1Nh0zkj3FPgBk%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;1672&quot; height=&quot;941&quot; data-filename=&quot;gradle.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;428&quot; data-start=&quot;387&quot; data-ke-size=&quot;size16&quot;&gt;Git으로 예전 프로젝트와 다시 연결하고 개발환경까지 어느 정도 세팅했다.&lt;/p&gt;
&lt;p data-end=&quot;476&quot; data-start=&quot;430&quot; data-ke-size=&quot;size16&quot;&gt;JDK 17을 설치하고, IntelliJ를 설치하고, GitHub도 다시 만들었다.&lt;/p&gt;
&lt;p data-end=&quot;520&quot; data-start=&quot;478&quot; data-ke-size=&quot;size16&quot;&gt;그리고 이제 실제로 Spring Boot 프로젝트를 하나 만들어보기로 했다.&lt;/p&gt;
&lt;p data-end=&quot;558&quot; data-start=&quot;522&quot; data-ke-size=&quot;size16&quot;&gt;그런데 프로젝트를 생성하자마자 익숙한 파일 하나가 눈에 들어왔다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;build.gradle&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;609&quot; data-start=&quot;586&quot; data-ke-size=&quot;size16&quot;&gt;예전 회사에서도 수도 없이 봤던 파일이다.&lt;/p&gt;
&lt;p data-end=&quot;637&quot; data-start=&quot;611&quot; data-ke-size=&quot;size16&quot;&gt;라이브러리가 필요하면 여기다가 한 줄 추가했고,&lt;/p&gt;
&lt;p data-end=&quot;666&quot; data-start=&quot;639&quot; data-ke-size=&quot;size16&quot;&gt;에러가 나면 Gradle Refresh를 눌렀고,&lt;/p&gt;
&lt;p data-end=&quot;698&quot; data-start=&quot;668&quot; data-ke-size=&quot;size16&quot;&gt;빌드가 안 되면 인터넷에서 검색해서 이것저것 수정했다.&lt;/p&gt;
&lt;p data-end=&quot;732&quot; data-start=&quot;700&quot; data-ke-size=&quot;size16&quot;&gt;그런데 다시 공부를 시작하면서 갑자기 이런 생각이 들었다.&lt;/p&gt;
&lt;blockquote data-end=&quot;761&quot; data-start=&quot;734&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;761&quot; data-start=&quot;736&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;근데 Gradle이 정확히 뭐였지?&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;775&quot; data-start=&quot;763&quot; data-ke-size=&quot;size16&quot;&gt;사용할 줄은 알았는데,&lt;/p&gt;
&lt;p data-end=&quot;797&quot; data-start=&quot;777&quot; data-ke-size=&quot;size16&quot;&gt;왜 쓰는지는 제대로 설명하지 못했다.&lt;/p&gt;
&lt;hr data-end=&quot;802&quot; data-start=&quot;799&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;833&quot; data-start=&quot;804&quot; data-ke-size=&quot;size26&quot;&gt;Gradle은 프로젝트를 만들어주는 빌드 도구다&lt;/h2&gt;
&lt;p data-end=&quot;881&quot; data-start=&quot;835&quot; data-ke-size=&quot;size16&quot;&gt;Java 파일을 작성했다고 해서 바로 우리가 사용하는 프로그램이 되는 것은 아니다.&lt;/p&gt;
&lt;p data-end=&quot;896&quot; data-start=&quot;883&quot; data-ke-size=&quot;size16&quot;&gt;코드를 컴파일해야 하고,&lt;/p&gt;
&lt;p data-end=&quot;917&quot; data-start=&quot;898&quot; data-ke-size=&quot;size16&quot;&gt;필요한 라이브러리를 가져와야 하고,&lt;/p&gt;
&lt;p data-end=&quot;930&quot; data-start=&quot;919&quot; data-ke-size=&quot;size16&quot;&gt;테스트도 해야 하고,&lt;/p&gt;
&lt;p data-end=&quot;963&quot; data-start=&quot;932&quot; data-ke-size=&quot;size16&quot;&gt;마지막에는 실행 가능한 jar 파일도 만들어야 한다.&lt;/p&gt;
&lt;p data-end=&quot;992&quot; data-start=&quot;965&quot; data-ke-size=&quot;size16&quot;&gt;이 과정을 직접 하나하나 하기에는 너무 번거롭다.&lt;/p&gt;
&lt;p data-end=&quot;1023&quot; data-start=&quot;994&quot; data-ke-size=&quot;size16&quot;&gt;그래서 사용하는 것이 &lt;b&gt;Build Tool&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;1057&quot; data-start=&quot;1025&quot; data-ke-size=&quot;size16&quot;&gt;Java에서는 대표적으로 Maven과 Gradle이 있다.&lt;/p&gt;
&lt;p data-end=&quot;1067&quot; data-start=&quot;1059&quot; data-ke-size=&quot;size16&quot;&gt;Gradle에게&lt;/p&gt;
&lt;blockquote data-end=&quot;1134&quot; data-start=&quot;1069&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1134&quot; data-start=&quot;1071&quot; data-ke-size=&quot;size16&quot;&gt;이 프로젝트는 Java 17을 사용하고&lt;br /&gt;Spring Boot를 사용하고&lt;br /&gt;이런 라이브러리들이 필요해.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1144&quot; data-start=&quot;1136&quot; data-ke-size=&quot;size16&quot;&gt;라고 알려주면,&lt;/p&gt;
&lt;p data-end=&quot;1182&quot; data-start=&quot;1146&quot; data-ke-size=&quot;size16&quot;&gt;Gradle이 필요한 라이브러리를 가져오고 프로젝트를 빌드해준다.&lt;/p&gt;
&lt;hr data-end=&quot;1187&quot; data-start=&quot;1184&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1224&quot; data-start=&quot;1189&quot; data-ke-size=&quot;size26&quot;&gt;dependencies는 단순한 라이브러리 목록이 아니었다&lt;/h2&gt;
&lt;p data-end=&quot;1259&quot; data-start=&quot;1226&quot; data-ke-size=&quot;size16&quot;&gt;Spring Boot 프로젝트를 만들면 이런 코드가 보인다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1445&quot; data-start=&quot;1438&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 그냥&lt;/p&gt;
&lt;p data-end=&quot;1466&quot; data-start=&quot;1447&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;라이브러리 추가하는 곳.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1477&quot; data-start=&quot;1468&quot; data-ke-size=&quot;size16&quot;&gt;이라고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;1504&quot; data-start=&quot;1479&quot; data-ke-size=&quot;size16&quot;&gt;틀린 설명은 아니지만 조금 더 정확히 말하면,&lt;/p&gt;
&lt;p data-end=&quot;1568&quot; data-start=&quot;1506&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;현재 프로젝트가 동작하기 위해 필요한 의존성(Dependency)을 Gradle에게 알려주는 부분&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;1575&quot; data-start=&quot;1570&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;clean&quot;&gt;&lt;code&gt;implementation 'org.springframework.boot:spring-boot-starter-web'&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1710&quot; data-start=&quot;1658&quot; data-ke-size=&quot;size16&quot;&gt;을 추가하면 웹 개발에 필요한 Spring MVC 관련 라이브러리들을 Gradle이 가져온다.&lt;/p&gt;
&lt;p data-end=&quot;1748&quot; data-start=&quot;1712&quot; data-ke-size=&quot;size16&quot;&gt;예전처럼 필요한 jar 파일을 직접 찾아서 넣을 필요가 없다.&lt;/p&gt;
&lt;p data-end=&quot;1779&quot; data-start=&quot;1750&quot; data-ke-size=&quot;size16&quot;&gt;생각해보면 나는 이 편리한 기능을 매일 사용하면서도,&lt;/p&gt;
&lt;p data-end=&quot;1820&quot; data-start=&quot;1781&quot; data-ke-size=&quot;size16&quot;&gt;정작 Gradle이 무슨 일을 하는지는 별로 생각하지 않았던 것 같다.&lt;/p&gt;
&lt;hr data-end=&quot;1825&quot; data-start=&quot;1822&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1846&quot; data-start=&quot;1827&quot; data-ke-size=&quot;size26&quot;&gt;gradlew는 또 뭐였을까?&lt;/h2&gt;
&lt;p data-end=&quot;1869&quot; data-start=&quot;1848&quot; data-ke-size=&quot;size16&quot;&gt;프로젝트 안을 보면 이런 파일도 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;gradlew
gradlew.bat&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1932&quot; data-start=&quot;1904&quot; data-ke-size=&quot;size16&quot;&gt;그리고 빌드할 때는 이런 명령어를 사용할 수 있다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;./gradlew build&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1973&quot; data-start=&quot;1963&quot; data-ke-size=&quot;size16&quot;&gt;Windows에서는&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;gradlew.bat build&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2033&quot; data-start=&quot;2006&quot; data-ke-size=&quot;size16&quot;&gt;이걸 &lt;b&gt;Gradle Wrapper&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-end=&quot;2042&quot; data-start=&quot;2035&quot; data-ke-size=&quot;size16&quot;&gt;쉽게 말하면,&lt;/p&gt;
&lt;blockquote data-end=&quot;2092&quot; data-start=&quot;2044&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2092&quot; data-start=&quot;2046&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;이 프로젝트가 사용하는 Gradle 환경을 프로젝트에 같이 넣어두는 것.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2103&quot; data-start=&quot;2094&quot; data-ke-size=&quot;size16&quot;&gt;이라고 이해했다.&lt;/p&gt;
&lt;p data-end=&quot;2125&quot; data-start=&quot;2105&quot; data-ke-size=&quot;size16&quot;&gt;개발자마다 Gradle 버전이 다르면&lt;/p&gt;
&lt;p data-end=&quot;2142&quot; data-start=&quot;2127&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;내 컴퓨터에서는 되는데?&amp;rdquo;&lt;/p&gt;
&lt;p data-end=&quot;2159&quot; data-start=&quot;2144&quot; data-ke-size=&quot;size16&quot;&gt;같은 상황이 생길 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2232&quot; data-start=&quot;2161&quot; data-ke-size=&quot;size16&quot;&gt;Gradle Wrapper를 사용하면 프로젝트에서 지정한 Gradle 환경으로 실행할 수 있기 때문에 개발환경 차이를 줄여준다.&lt;/p&gt;
&lt;hr data-end=&quot;2237&quot; data-start=&quot;2234&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;2273&quot; data-start=&quot;2239&quot;&gt;그리고 이번에는 Claude Code도 같이 쓰기 시작했다&lt;/h1&gt;
&lt;p data-end=&quot;2300&quot; data-start=&quot;2275&quot; data-ke-size=&quot;size16&quot;&gt;이번 공부에서 예전과 달라진 것이 하나 있다.&lt;/p&gt;
&lt;p data-end=&quot;2331&quot; data-start=&quot;2302&quot; data-ke-size=&quot;size16&quot;&gt;AI 개발 도구를 적극적으로 사용하고 있다는 것이다.&lt;/p&gt;
&lt;p data-end=&quot;2376&quot; data-start=&quot;2333&quot; data-ke-size=&quot;size16&quot;&gt;나는 요즘 &lt;b&gt;Claude Code(클로드 코드)&lt;/b&gt;도 같이 사용하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;2403&quot; data-start=&quot;2378&quot; data-ke-size=&quot;size16&quot;&gt;예전 같았으면 Gradle 오류가 발생했을 때&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;mathematica&quot;&gt;&lt;code&gt;에러 메시지 복사
&amp;darr;
구글 검색
&amp;darr;
Stack Overflow
&amp;darr;
블로그 여러 개 확인
&amp;darr;
코드 수정&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2486&quot; data-start=&quot;2475&quot; data-ke-size=&quot;size16&quot;&gt;이런 과정을 거쳤다.&lt;/p&gt;
&lt;p data-end=&quot;2525&quot; data-start=&quot;2488&quot; data-ke-size=&quot;size16&quot;&gt;지금은 터미널에서 Claude Code에게 바로 물어볼 수도 있다.&lt;/p&gt;
&lt;p data-end=&quot;2532&quot; data-start=&quot;2527&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;blockquote data-end=&quot;2579&quot; data-start=&quot;2534&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2579&quot; data-start=&quot;2536&quot; data-ke-size=&quot;size16&quot;&gt;build.gradle에서 이 dependency가 왜 필요한지 설명해줘.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2583&quot; data-start=&quot;2581&quot; data-ke-size=&quot;size16&quot;&gt;혹은&lt;/p&gt;
&lt;blockquote data-end=&quot;2627&quot; data-start=&quot;2585&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2627&quot; data-start=&quot;2587&quot; data-ke-size=&quot;size16&quot;&gt;현재 프로젝트의 Gradle 설정을 확인하고 문제가 있는 부분을 찾아줘.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2641&quot; data-start=&quot;2629&quot; data-ke-size=&quot;size16&quot;&gt;처럼 질문할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2681&quot; data-start=&quot;2643&quot; data-ke-size=&quot;size16&quot;&gt;코드 전체 흐름을 보면서 설명을 받을 수 있다는 점은 확실히 편했다.&lt;/p&gt;
&lt;hr data-end=&quot;2686&quot; data-start=&quot;2683&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2718&quot; data-start=&quot;2688&quot; data-ke-size=&quot;size26&quot;&gt;하지만 AI에게 코드를 맡기는 것이 목표는 아니다&lt;/h2&gt;
&lt;p data-end=&quot;2740&quot; data-start=&quot;2720&quot; data-ke-size=&quot;size16&quot;&gt;여기서 내가 정한 원칙이 하나 있다.&lt;/p&gt;
&lt;p data-end=&quot;2768&quot; data-start=&quot;2742&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AI가 작성했다고 그냥 넘어가지 않는다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2794&quot; data-start=&quot;2770&quot; data-ke-size=&quot;size16&quot;&gt;Claude Code가 코드를 만들어주더라도&lt;/p&gt;
&lt;p data-end=&quot;2808&quot; data-start=&quot;2796&quot; data-ke-size=&quot;size16&quot;&gt;왜 이렇게 작성했는지,&lt;/p&gt;
&lt;p data-end=&quot;2833&quot; data-start=&quot;2810&quot; data-ke-size=&quot;size16&quot;&gt;Gradle에서는 어떤 설정이 바뀌었는지,&lt;/p&gt;
&lt;p data-end=&quot;2859&quot; data-start=&quot;2835&quot; data-ke-size=&quot;size16&quot;&gt;Spring에서는 이것이 어떤 역할을 하는지&lt;/p&gt;
&lt;p data-end=&quot;2878&quot; data-start=&quot;2861&quot; data-ke-size=&quot;size16&quot;&gt;한 번은 직접 확인하려고 한다.&lt;/p&gt;
&lt;p data-end=&quot;2904&quot; data-start=&quot;2880&quot; data-ke-size=&quot;size16&quot;&gt;이번에 다시 개발 공부를 시작한 이유 자체가&lt;/p&gt;
&lt;p data-end=&quot;2976&quot; data-start=&quot;2906&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;코드를 빨리 만드는 개발자보다, 내가 작성한 코드가 왜 동작하는지 설명할 수 있는 개발자가 되고 싶어서&lt;/b&gt;이기 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;3009&quot; data-start=&quot;2978&quot; data-ke-size=&quot;size16&quot;&gt;AI는 그 과정을 빠르게 도와주는 도구로 사용하고 있다.&lt;/p&gt;
&lt;hr data-end=&quot;3014&quot; data-start=&quot;3011&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 data-end=&quot;3032&quot; data-start=&quot;3016&quot;&gt;예전에는 실행만 되면 됐다&lt;/h1&gt;
&lt;p data-end=&quot;3054&quot; data-start=&quot;3034&quot; data-ke-size=&quot;size16&quot;&gt;회사에서 개발할 때는 일정이 있었다.&lt;/p&gt;
&lt;p data-end=&quot;3068&quot; data-start=&quot;3056&quot; data-ke-size=&quot;size16&quot;&gt;기능을 만들어야 했고,&lt;/p&gt;
&lt;p data-end=&quot;3088&quot; data-start=&quot;3070&quot; data-ke-size=&quot;size16&quot;&gt;오류가 나면 빨리 해결해야 했고,&lt;/p&gt;
&lt;p data-end=&quot;3109&quot; data-start=&quot;3090&quot; data-ke-size=&quot;size16&quot;&gt;서비스를 완성하는 것이 우선이었다.&lt;/p&gt;
&lt;p data-end=&quot;3114&quot; data-start=&quot;3111&quot; data-ke-size=&quot;size16&quot;&gt;그래서&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;build.gradle 수정
&amp;rarr; Gradle Refresh
&amp;rarr; 실행&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3183&quot; data-start=&quot;3167&quot; data-ke-size=&quot;size16&quot;&gt;되면 넘어가는 경우가 많았다.&lt;/p&gt;
&lt;p data-end=&quot;3213&quot; data-start=&quot;3185&quot; data-ke-size=&quot;size16&quot;&gt;하지만 다시 공부하면서 조금씩 질문을 바꾸고 있다.&lt;/p&gt;
&lt;p data-end=&quot;3231&quot; data-start=&quot;3215&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;어떻게 하면 되지?&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3235&quot; data-start=&quot;3233&quot; data-ke-size=&quot;size16&quot;&gt;에서&lt;/p&gt;
&lt;p data-end=&quot;3255&quot; data-start=&quot;3237&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;왜 이렇게 되는 거지?&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3259&quot; data-start=&quot;3257&quot; data-ke-size=&quot;size16&quot;&gt;로.&lt;/p&gt;
&lt;p data-end=&quot;3274&quot; data-start=&quot;3261&quot; data-ke-size=&quot;size16&quot;&gt;Git을 다시 공부했고,&lt;/p&gt;
&lt;p data-end=&quot;3298&quot; data-start=&quot;3276&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 Gradle을 다시 보고 있다.&lt;/p&gt;
&lt;p data-end=&quot;3349&quot; data-start=&quot;3300&quot; data-ke-size=&quot;size16&quot;&gt;그리고 예전에는 없었던 Claude Code 같은 AI 개발 도구도 같이 사용하고 있다.&lt;/p&gt;
&lt;p data-end=&quot;3364&quot; data-start=&quot;3351&quot; data-ke-size=&quot;size16&quot;&gt;기술은 많이 달라졌지만,&lt;/p&gt;
&lt;p data-end=&quot;3391&quot; data-start=&quot;3366&quot; data-ke-size=&quot;size16&quot;&gt;결국 개발자가 해야 할 일은 비슷한 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;3425&quot; data-start=&quot;3393&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;도구를 사용하는 것과 도구를 이해하는 것은 다르다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;3451&quot; data-start=&quot;3427&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 그 차이를 하나씩 채워보려고 한다.&lt;/p&gt;
&lt;p data-end=&quot;3577&quot; data-start=&quot;3511&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/5</guid>
      <comments>https://nocklock.tistory.com/5#entry5comment</comments>
      <pubDate>Wed, 16 Sep 2026 18:25:17 +0900</pubDate>
    </item>
    <item>
      <title>나는 구글이 무섭다</title>
      <link>https://nocklock.tistory.com/3</link>
      <description>&lt;h2 data-end=&quot;198&quot; data-start=&quot;165&quot; data-section-id=&quot;1idm64c&quot; data-ke-size=&quot;size26&quot;&gt;편리함에 익숙해진 순간, 내 삶은 누구의 것이 되었을까&lt;/h2&gt;
&lt;p data-end=&quot;218&quot; data-start=&quot;200&quot; data-ke-size=&quot;size16&quot;&gt;나는 구글을 정말 많이 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;304&quot; data-start=&quot;220&quot; data-ke-size=&quot;size16&quot;&gt;검색을 하고, 유튜브를 보고, 지도를 켜고, 메일을 확인한다.&lt;br /&gt;새로운 서비스를 가입할 때는 자연스럽게 &lt;b&gt;&amp;lsquo;Google로 계속하기&amp;rsquo;&lt;/b&gt;를 누른다.&lt;/p&gt;
&lt;p data-end=&quot;361&quot; data-start=&quot;306&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드 스마트폰을 사용한다면 연락처, 사진, 위치 기록, 일정까지 구글과 연결되는 경우도 많다.&lt;/p&gt;
&lt;p data-end=&quot;370&quot; data-start=&quot;363&quot; data-ke-size=&quot;size16&quot;&gt;너무 편하다.&lt;/p&gt;
&lt;p data-end=&quot;395&quot; data-start=&quot;372&quot; data-ke-size=&quot;size16&quot;&gt;그런데 어느 날 문득 이런 생각이 들었다.&lt;/p&gt;
&lt;p data-end=&quot;422&quot; data-start=&quot;397&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;만약 내 구글 계정이 내일 사라진다면?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;458&quot; data-start=&quot;424&quot; data-ke-size=&quot;size16&quot;&gt;생각보다 많은 것이 함께 사라질 수도 있겠다는 생각이 들었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;tumisu-seo-1018442_1920.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;644&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/npBBX/dJMcafuxd6f/MCEA7zCEkwtaaear4A5DP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/npBBX/dJMcafuxd6f/MCEA7zCEkwtaaear4A5DP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/npBBX/dJMcafuxd6f/MCEA7zCEkwtaaear4A5DP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnpBBX%2FdJMcafuxd6f%2FMCEA7zCEkwtaaear4A5DP1%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; alt=&quot;google&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;644&quot; data-filename=&quot;tumisu-seo-1018442_1920.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;644&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-end=&quot;463&quot; data-start=&quot;460&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;492&quot; data-start=&quot;465&quot; data-section-id=&quot;m529he&quot; data-ke-size=&quot;size23&quot;&gt;하나의 계정에 너무 많은 삶을 맡기고 있다&lt;/h3&gt;
&lt;p data-end=&quot;525&quot; data-start=&quot;494&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 인터넷 서비스마다 아이디와 비밀번호를 만들었다.&lt;/p&gt;
&lt;p data-end=&quot;532&quot; data-start=&quot;527&quot; data-ke-size=&quot;size16&quot;&gt;불편했다.&lt;/p&gt;
&lt;p data-end=&quot;548&quot; data-start=&quot;534&quot; data-ke-size=&quot;size16&quot;&gt;지금은 버튼 하나면 된다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;Google 계정

├─ Gmail
├─ YouTube
├─ Drive
├─ Photos
├─ Calendar
├─ Maps
└─ 다른 서비스의 소셜 로그인&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;682&quot; data-start=&quot;651&quot; data-ke-size=&quot;size16&quot;&gt;하나의 계정으로 모든 것이 연결되는 건 굉장히 편리하다.&lt;/p&gt;
&lt;p data-end=&quot;743&quot; data-start=&quot;684&quot; data-ke-size=&quot;size16&quot;&gt;하지만 반대로 생각하면 &lt;b&gt;하나의 계정에 문제가 생겼을 때 영향을 받는 범위도 그만큼 커졌다는 뜻&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;761&quot; data-start=&quot;745&quot; data-ke-size=&quot;size16&quot;&gt;나는 이 지점이 조금 무섭다.&lt;/p&gt;
&lt;p data-end=&quot;781&quot; data-start=&quot;763&quot; data-ke-size=&quot;size16&quot;&gt;구글이라는 회사가 무섭다기보다는,&lt;/p&gt;
&lt;p data-end=&quot;825&quot; data-start=&quot;783&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 너무 자연스럽게 하나의 플랫폼에 의존하고 있다는 사실이 무섭다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;830&quot; data-start=&quot;827&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;863&quot; data-start=&quot;832&quot; data-section-id=&quot;1b20fq4&quot; data-ke-size=&quot;size23&quot;&gt;개인정보보다 더 무서운 것은 '종속'일지도 모른다&lt;/h3&gt;
&lt;p data-end=&quot;900&quot; data-start=&quot;865&quot; data-ke-size=&quot;size16&quot;&gt;우리는 개인정보 문제를 이야기할 때 보통 유출을 먼저 생각한다.&lt;/p&gt;
&lt;p data-end=&quot;934&quot; data-start=&quot;902&quot; data-ke-size=&quot;size16&quot;&gt;이름, 전화번호, 주소, 비밀번호가 해커에게 넘어가는 것.&lt;/p&gt;
&lt;p data-end=&quot;944&quot; data-start=&quot;936&quot; data-ke-size=&quot;size16&quot;&gt;물론 중요하다.&lt;/p&gt;
&lt;p data-end=&quot;974&quot; data-start=&quot;946&quot; data-ke-size=&quot;size16&quot;&gt;하지만 나는 요즘 조금 다른 문제가 더 궁금해졌다.&lt;/p&gt;
&lt;p data-end=&quot;1065&quot; data-start=&quot;976&quot; data-ke-size=&quot;size16&quot;&gt;내 사진은 어디에 있는가?&lt;br /&gt;내 이메일은 어디에 있는가?&lt;br /&gt;내가 방문했던 장소는 누가 기억하고 있는가?&lt;br /&gt;내가 어떤 영상을 좋아하는지는 누가 알고 있는가?&lt;/p&gt;
&lt;p data-end=&quot;1077&quot; data-start=&quot;1067&quot; data-ke-size=&quot;size16&quot;&gt;그리고 더 나아가,&lt;/p&gt;
&lt;p data-end=&quot;1115&quot; data-start=&quot;1079&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 인터넷에서 살아온 흔적을 나는 얼마나 가지고 있는가?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1162&quot; data-start=&quot;1117&quot; data-ke-size=&quot;size16&quot;&gt;아이러니하게도 내 삶의 기록인데 내가 직접 가지고 있지 않은 것들이 굉장히 많다.&lt;/p&gt;
&lt;hr data-end=&quot;1167&quot; data-start=&quot;1164&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1196&quot; data-start=&quot;1169&quot; data-section-id=&quot;27b62o&quot; data-ke-size=&quot;size23&quot;&gt;AI 시대에는 이 문제가 더 커질 것 같다&lt;/h3&gt;
&lt;p data-end=&quot;1241&quot; data-start=&quot;1198&quot; data-ke-size=&quot;size16&quot;&gt;앞으로 AI는 우리가 직접 입력한 질문만 가지고 우리를 이해하지 않을 것이다.&lt;/p&gt;
&lt;p data-end=&quot;1327&quot; data-start=&quot;1243&quot; data-ke-size=&quot;size16&quot;&gt;우리가 읽은 글, 본 영상, 검색한 것, 구매한 것, 방문한 장소 같은 여러 데이터가 연결될수록 AI는 개인에게 훨씬 정확한 서비스를 제공할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1342&quot; data-start=&quot;1329&quot; data-ke-size=&quot;size16&quot;&gt;엄청나게 편리할 것이다.&lt;/p&gt;
&lt;p data-end=&quot;1361&quot; data-start=&quot;1344&quot; data-ke-size=&quot;size16&quot;&gt;동시에 한 가지 질문이 생긴다.&lt;/p&gt;
&lt;blockquote data-end=&quot;1409&quot; data-start=&quot;1363&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1409&quot; data-start=&quot;1365&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그 AI가 나를 이해하기 위해 사용하는 '나의 데이터'는 누구의 것일까?&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1423&quot; data-start=&quot;1411&quot; data-ke-size=&quot;size16&quot;&gt;나는 AI를 좋아한다.&lt;/p&gt;
&lt;p data-end=&quot;1457&quot; data-start=&quot;1425&quot; data-ke-size=&quot;size16&quot;&gt;오히려 적극적으로 사용하고 있고, 개발에도 활용하려 한다.&lt;/p&gt;
&lt;p data-end=&quot;1470&quot; data-start=&quot;1459&quot; data-ke-size=&quot;size16&quot;&gt;그래서 더 궁금하다.&lt;/p&gt;
&lt;p data-end=&quot;1551&quot; data-start=&quot;1472&quot; data-ke-size=&quot;size16&quot;&gt;AI를 사용하지 않는 세상으로 돌아가는 것이 아니라, &lt;b&gt;AI를 사용하면서도 내 데이터에 대한 통제권을 내가 가질 수 있는 방법은 없을까?&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1556&quot; data-start=&quot;1553&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1578&quot; data-start=&quot;1558&quot; data-section-id=&quot;1173bkz&quot; data-ke-size=&quot;size23&quot;&gt;그래서 직접 공부해보려고 한다&lt;/h3&gt;
&lt;p data-end=&quot;1589&quot; data-start=&quot;1580&quot; data-ke-size=&quot;size16&quot;&gt;아직 답은 없다.&lt;/p&gt;
&lt;p data-end=&quot;1610&quot; data-start=&quot;1591&quot; data-ke-size=&quot;size16&quot;&gt;구글을 탈퇴하자는 이야기도 아니다.&lt;/p&gt;
&lt;p data-end=&quot;1642&quot; data-start=&quot;1612&quot; data-ke-size=&quot;size16&quot;&gt;나 역시 내일도 구글 검색을 하고 유튜브를 볼 것이다.&lt;/p&gt;
&lt;p data-end=&quot;1671&quot; data-start=&quot;1644&quot; data-ke-size=&quot;size16&quot;&gt;대신 개발자로서 조금 더 깊게 들여다보려고 한다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;내 데이터는 어디에 저장되는가
          &amp;darr;
서비스는 나를 어떻게 식별하는가
          &amp;darr;
로그인과 인증은 어떻게 이루어지는가
          &amp;darr;
플랫폼은 어떤 데이터를 수집하는가
          &amp;darr;
나는 내 데이터를 가져올 수 있는가
          &amp;darr;
내가 직접 통제할 방법은 없는가&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1923&quot; data-start=&quot;1858&quot; data-ke-size=&quot;size16&quot;&gt;OAuth, 쿠키, 세션, 토큰, 개인정보보호, 데이터 이동권, 암호화 같은 기술들도 하나씩 다시 공부해볼 생각이다.&lt;/p&gt;
&lt;p data-end=&quot;1967&quot; data-start=&quot;1925&quot; data-ke-size=&quot;size16&quot;&gt;그리고 가능하다면 공부로 끝내지 않고 &lt;b&gt;직접 서비스를 만들어보고 싶다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1972&quot; data-start=&quot;1969&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1993&quot; data-start=&quot;1974&quot; data-section-id=&quot;1nshjh6&quot; data-ke-size=&quot;size23&quot;&gt;편리함을 버리고 싶지는 않다&lt;/h3&gt;
&lt;p data-end=&quot;2015&quot; data-start=&quot;1995&quot; data-ke-size=&quot;size16&quot;&gt;나는 기술이 주는 편리함을 좋아한다.&lt;/p&gt;
&lt;p data-end=&quot;2038&quot; data-start=&quot;2017&quot; data-ke-size=&quot;size16&quot;&gt;구글도 사용하고 AI도 사용할 것이다.&lt;/p&gt;
&lt;p data-end=&quot;2070&quot; data-start=&quot;2040&quot; data-ke-size=&quot;size16&quot;&gt;하지만 편리함의 대가가 무엇인지는 알고 사용하고 싶다.&lt;/p&gt;
&lt;p data-end=&quot;2105&quot; data-start=&quot;2072&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;편리한 것과 종속되는 것은 같은 말이 아니어야 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2150&quot; data-start=&quot;2107&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이 글은 구글에 대한 비판이라기보다 나 자신에게 던지는 질문에 가깝다.&lt;/p&gt;
&lt;blockquote data-end=&quot;2179&quot; data-start=&quot;2152&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2179&quot; data-start=&quot;2154&quot; data-ke-size=&quot;size16&quot;&gt;나는 내 디지털 삶을 얼마나 통제하고 있는가?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2192&quot; data-start=&quot;2181&quot; data-ke-size=&quot;size16&quot;&gt;아직 답을 모르겠다.&lt;/p&gt;
&lt;p data-end=&quot;2214&quot; data-start=&quot;2194&quot; data-ke-size=&quot;size16&quot;&gt;그래서 앞으로 직접 알아보려고 한다.&lt;/p&gt;
&lt;p data-end=&quot;2231&quot; data-start=&quot;2216&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;나는 구글이 무섭다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2238&quot; data-start=&quot;2233&quot; data-ke-size=&quot;size16&quot;&gt;정확히는,&lt;/p&gt;
&lt;p data-end=&quot;2269&quot; data-start=&quot;2240&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;구글 없이는 불편해진 나 자신이 조금 무섭다.&lt;/b&gt;&lt;/p&gt;</description>
      <category>기술이 조금 무섭다</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/3</guid>
      <comments>https://nocklock.tistory.com/3#entry3comment</comments>
      <pubDate>Wed, 16 Sep 2026 11:17:04 +0900</pubDate>
    </item>
    <item>
      <title>지금 나와있는 AI 툴 모아봤다! &amp;mdash; 2026 AI 툴 총정리</title>
      <link>https://nocklock.tistory.com/4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;요즘 정말 하루가 멀다 하고 새로운 AI가 나온다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;ChatGPT는 알겠는데 Claude도 있고, Gemini도 있고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개발하려고 보면 Cursor와 Copilot이 나오고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이미지를 만들려고 하면 Midjourney와 Firefly,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;영상을 만들려고 하면 Runway와 Kling이 나온다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그러다 보니 이런 생각이 들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;ldquo;그래서 지금 AI 툴이 대체 얼마나 많은 거야?&amp;rdquo;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 한번 정리해보기로 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;※ 이 글은 &lt;/span&gt;&lt;b&gt;&lt;span&gt;2026년 9월 16일 기준&lt;/span&gt;&lt;/b&gt;&lt;span&gt;이다. 세상에 존재하는 AI 서비스를 문자 그대로 전부 나열하기보다는 현재 실제로 많이 사용되고 있거나 알아둘 만한 대표적인 서비스를 용도별로 정리했다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcANuD/dJMcafIcXOf/iSAMKTJBwSULbVgQNtdA7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcANuD/dJMcafIcXOf/iSAMKTJBwSULbVgQNtdA7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcANuD/dJMcafIcXOf/iSAMKTJBwSULbVgQNtdA7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcANuD%2FdJMcafIcXOf%2FiSAMKTJBwSULbVgQNtdA7k%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;1672&quot; height=&quot;941&quot; data-filename=&quot;image.png&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;1. 일단 AI에게 뭐든 물어보고 싶다면&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;ChatGPT&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;아마 가장 먼저 떠오르는 생성형 AI.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;질문, 글쓰기, 번역, 코딩, 파일 분석, 이미지 생성, 웹 검색 등 이제는 단순한 챗봇이라기보다 범용 AI 작업환경에 가까워졌다. 현재 ChatGPT는 웹 검색과 파일&amp;middot;이미지 등을 활용한 다양한 작업을 지원한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;추천 용도:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 그냥 AI 하나만 먼저 써보고 싶은 사람, 공부, 글쓰기, 코딩, 아이디어 정리&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Claude&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Anthropic이 만든 AI.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;긴 문서를 읽거나 글을 다듬는 작업, 개발과 지식 업무에서 많이 사용된다. Anthropic은 2026년에도 Claude 모델을 계속 업데이트하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;추천 용도:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 긴 글, 문서 분석, 코딩, 논리적인 글 작성&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Gemini&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Google의 AI.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Google 서비스와 연결되는 것이 가장 큰 특징 중 하나다. Gemini 앱뿐 아니라 Google의 여러 서비스와 AI 기능이 점점 통합되는 방향으로 발전하고 있다. 2026년 Google은 Gemini 기반 에이전트 기능도 크게 확장했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;추천 용도:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; Google 서비스를 많이 사용하는 사람, 자료 정리, 멀티모달 작업&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Microsoft Copilot&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Microsoft 생태계의 AI.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Windows와 Microsoft 365 환경을 자주 사용한다면 자연스럽게 접하게 되는 AI다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Perplexity&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI 검색에 특화된 서비스.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;질문을 입력하면 웹을 검색하고 답변과 함께 출처를 제공하는 형태라서 자료 조사할 때 편하다. 일반 Search, Pro Search, Deep Research 등의 기능을 제공한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;추천 용도:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 블로그 자료조사, 최신 정보 검색, 리서치&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;2. 개발자라면 알아둘 AI&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;여기는 개인적으로 가장 관심 있는 분야다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI가 코드를 한 줄 자동완성하는 수준을 넘어 이제는 프로젝트를 읽고, 파일을 수정하고, 터미널을 실행하고, 테스트까지 수행하는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;AI Agent&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 형태로 발전하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;GitHub Copilot&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개발자에게 가장 익숙한 AI 도구 중 하나.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;VS Code, JetBrains 등의 IDE에서 코드 자동완성, 코드 설명, 수정, Agent Mode 등을 지원하고 GitHub 자체에서도 AI Agent를 활용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Cursor&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI 개발에 특화된 코드 에디터.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;프로젝트 전체 코드베이스를 읽고 여러 파일을 수정하거나 터미널 명령어를 실행할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2026년의 Cursor는 단순 코드 자동완성 도구라기보다 여러 Agent와 함께 개발하는 방향으로 발전하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Claude Code&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Claude를 터미널과 개발환경에서 활용하는 개발 도구.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;코드베이스 분석, 수정, 테스트 등의 개발 작업에 활용된다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;OpenAI Codex&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;OpenAI의 개발용 AI Agent.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;코드를 질문하는 것을 넘어 실제 개발 작업 단위로 AI에게 일을 맡기는 방향의 도구다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Windsurf&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Cursor와 함께 자주 비교되는 AI 기반 개발환경.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI와 대화하면서 프로젝트를 수정하고 개발하는 Agent형 개발 방식에 초점을 맞추고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Replit Agent&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;ldquo;앱 하나 만들어줘&amp;rdquo;라고 자연어로 요청하면 실제 앱을 만들어주는 방식의 서비스.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2026년 공개된 Agent 4는 웹&amp;middot;모바일 앱뿐 아니라 데이터 대시보드와 AI 도구 제작까지 지원한다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Lovable&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;자연어로 웹 애플리케이션을 만드는 AI 개발 플랫폼.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;프론트엔드뿐 아니라 백엔드, 인증, 데이터베이스, 연동까지 포함하는 풀스택 애플리케이션 개발을 목표로 한다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Bolt&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;프롬프트를 입력해 웹 애플리케이션을 만들고 바로 실행&amp;middot;배포하는 방식의 AI 앱 빌더다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결국 개발 AI는 크게 보면&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;Copilot &amp;rarr; 개발 보조&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;Cursor / Claude Code / Codex &amp;rarr; AI와 함께 개발&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;Lovable / Replit / Bolt &amp;rarr; 자연어에서 앱 자체를 생성&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정도로 이해하면 꽤 쉽다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;3. 이미지 생성 AI&lt;/span&gt;&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Midjourney&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI 이미지 생성 분야에서 가장 유명한 서비스 중 하나.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2026년 7월에는 V8.2가 기본 이미지 모델로 공개됐고, 이미지뿐 아니라 영상 기능도 제공하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;추천:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 감성 이미지, 콘셉트 아트, 디자인&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Adobe Firefly&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Adobe의 생성형 AI 플랫폼.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이미지 생성뿐 아니라 이미지 편집, 영상, 오디오, 벡터 생성까지 지원한다. Adobe뿐 아니라 여러 파트너 AI 모델도 하나의 환경에서 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;추천:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; Photoshop이나 Adobe 제품을 사용하는 디자이너&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;ChatGPT 이미지 생성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;대화하면서 바로 이미지를 만들거나 수정할 수 있다는 게 장점이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;ldquo;여기 글씨만 바꿔줘.&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;ldquo;배경을 밤으로 만들어줘.&amp;rdquo;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처럼 대화 방식으로 수정하기 편하다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Canva Magic Studio&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Canva 안에서 AI를 이용해 이미지와 디자인, 콘텐츠 제작 등을 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;디자인을 전문적으로 하지 않는 사람에게 특히 접근성이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Ideogram / Leonardo AI&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이미지 생성과 디자인 작업에서 많이 언급되는 서비스들이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;특히 이미지 안의 텍스트 표현이나 다양한 스타일 제작이 필요할 때 비교해볼 만하다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;4. 영상 생성 AI&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI 영상 분야는 현재 가장 빠르게 변하고 있는 영역 중 하나다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Google Flow / Veo&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Google의 AI 영상 제작 환경.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Flow에서는 Veo 계열 모델 등을 이용해 텍스트나 이미지를 영상으로 만드는 기능을 제공한다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Runway&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI 영상 제작 분야의 대표적인 서비스.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 Gen-4.5는 Text-to-Video와 Image-to-Video 등을 지원하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Kling AI&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이미지와 영상을 생성하는 AI 플랫폼.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 Kling 3.0 계열을 중심으로 영상 생성, 이미지 생성, 사운드 및 모션 관련 기능을 제공한다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Pika&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;짧은 AI 영상이나 특수한 영상 효과를 만들기 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Pika Agent와 영상 제작 기능도 제공하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Luma AI&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI 이미지&amp;middot;영상 생성 플랫폼.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;과거 Dream Machine으로 많이 알려졌지만 현재 Luma는 Ray 계열 영상 모델과 UNI 계열 모델을 중심으로 서비스하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;그런데 Sora는?&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;여기서 의외의 사실 하나.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;OpenAI의 AI 영상 서비스 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Sora는 2026년 4월 26일 종료됐다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예전 AI 도구 소개 글에는 Sora가 거의 항상 들어가 있기 때문에 최신 AI 툴을 검색할 때는 글의 작성 날짜도 꼭 확인해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;5. 목소리&amp;middot;음악 AI&lt;/span&gt;&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;ElevenLabs&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI 음성 분야의 대표적인 서비스.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Text-to-Speech, Speech-to-Text, Voice Cloning뿐 아니라 음성 기반 AI Agent 기능까지 제공한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;추천:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 내레이션, 더빙, 음성 서비스 개발&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Suno&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;프롬프트만으로 노래를 만들 수 있는 AI 음악 서비스.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2026년 9월에는 v6 계열 음악 모델이 공개됐다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Udio&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Suno와 함께 AI 음악 생성 분야에서 많이 언급되는 서비스다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;노래 제작이나 음악 아이디어를 만들 때 비교해서 사용해볼 만하다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;6. 문서&amp;middot;PPT&amp;middot;업무용 AI&lt;/span&gt;&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Notion AI&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;단순히 글을 써주는 기능에서 훨씬 발전했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재는 Notion Agent, AI Meeting Notes, Enterprise Search, 반복 업무를 처리하는 Custom Agent 등까지 제공한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;추천:&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 회사 문서, 프로젝트 관리, 회의 정리&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Gamma&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;주제나 글을 넣으면 AI가 프레젠테이션과 문서, 웹페이지 등을 만들어준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;PPT로 내보내는 것도 가능해서 발표 자료를 빠르게 만들 때 편하다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Canva&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;디자인뿐 아니라 발표자료, SNS 콘텐츠 등을 AI와 함께 만들 수 있기 때문에 비개발자에게 특히 활용도가 높다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;7. 논문&amp;middot;공부&amp;middot;리서치 AI&lt;/span&gt;&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;NotebookLM&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;내가 넣은 자료를 기반으로 질문하고 정리하는 Google의 AI 도구.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;PDF나 자료를 넣고 공부하거나 내용을 정리할 때 특히 유용하다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Consensus&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;논문 검색에 특화된 AI 검색엔진.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;일반 웹페이지가 아니라 학술 연구를 중심으로 검색하며, 현재 2억 2천만 편 이상의 peer-reviewed 연구 논문 데이터베이스를 대상으로 검색한다고 설명하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Elicit&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;연구자를 위한 AI Research Assistant.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;논문 조사나 문헌 검토 같은 연구 업무를 효율화하는 데 초점을 맞춘 서비스다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;Perplexity&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;일반 리서치에서는 여전히 매우 편하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;검색 결과와 출처를 함께 확인할 수 있기 때문에 블로그 자료조사를 할 때도 활용하기 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;그러면 뭘 써야 할까?&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사실 모든 AI를 사용할 필요는 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;내가 지금 기준으로 AI를 처음 사용하는 사람에게 설명한다면 이렇게 말할 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;평소에는 ChatGPT&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;자료 검색은 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Perplexity&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;긴 문서나 글 작업은 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Claude&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Google 사용자라면 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Gemini&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개발자는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Cursor + GitHub Copilot + Claude Code/Codex&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이미지는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Midjourney 또는 Firefly&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;영상은 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Runway / Kling / Google Flow&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;목소리는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;ElevenLabs&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;음악은 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Suno&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;발표자료는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Gamma&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;문서와 업무관리는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Notion AI&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;논문 검색은 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Consensus / Elicit&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정도부터 시작하면 충분하다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;AI는 이제 하나의 프로그램이 아니다&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에 정리하면서 가장 크게 느낀 점은 이것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;몇 년 전만 해도&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;ldquo;ChatGPT 써봤어?&amp;rdquo;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;가 질문이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;지금은 조금 다르다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;글을 쓰는 AI,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;검색하는 AI,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;코딩하는 AI,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;앱을 만들어주는 AI,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그림을 그리는 AI,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;영상을 만드는 AI,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;노래를 만드는 AI,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 직접 컴퓨터를 조작하고 일을 수행하는 Agent까지 등장하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 앞으로 중요한 능력은&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;AI를 알고 있느냐가 아니라, 어떤 일을 어떤 AI에게 맡길지 판단하는 능력&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 되지 않을까 싶다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;나 역시 개발자로 다시 공부하면서 AI를 단순히 질문하는 도구가 아니라 실제 개발 도구로 사용해보고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;앞으로 이 블로그에서는 여기 적은 AI들을 하나씩 직접 써보면서&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;무료로 어디까지 가능한지,&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;실제로 쓸 만한지,&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;개발자에게 어떤 도움이 되는지&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하나씩 정리해볼 생각이다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2026.09.16 기준. AI 서비스는 변화 속도가 매우 빠르기 때문에 기능과 모델, 요금제는 이후 달라질 수 있습니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>AI TOOLS</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/4</guid>
      <comments>https://nocklock.tistory.com/4#entry4comment</comments>
      <pubDate>Wed, 16 Sep 2026 09:22:12 +0900</pubDate>
    </item>
    <item>
      <title>Git을 매일 썼는데, 다시 시작하니 아무것도 기억나지 않았다 | RE:개발자 #2</title>
      <link>https://nocklock.tistory.com/2</link>
      <description>&lt;h2 data-end=&quot;150&quot; data-start=&quot;135&quot; data-section-id=&quot;518it3&quot; data-ke-size=&quot;size26&quot;&gt;Git, 다시 연결하다&lt;/h2&gt;
&lt;p data-end=&quot;183&quot; data-start=&quot;152&quot; data-ke-size=&quot;size16&quot;&gt;1편을 쓰고 나서 실제 개발환경을 다시 만들기 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;253&quot; data-start=&quot;185&quot; data-ke-size=&quot;size16&quot;&gt;JDK 17을 설치하고, IntelliJ를 설치하고, 그리고 GitHub에 만들어둔 프로젝트를 내 PC로 가져오기로 했다.&lt;/p&gt;
&lt;p data-end=&quot;274&quot; data-start=&quot;255&quot; data-ke-size=&quot;size16&quot;&gt;회사에서는 Git을 매일같이 썼다.&lt;/p&gt;
&lt;p data-end=&quot;301&quot; data-start=&quot;276&quot; data-ke-size=&quot;size16&quot;&gt;pull, commit, push.&lt;/p&gt;
&lt;p data-end=&quot;357&quot; data-start=&quot;303&quot; data-ke-size=&quot;size16&quot;&gt;그런데 막상 아무것도 없는 PC에서 처음부터 다시 시작하려니 생각보다 손이 바로 움직이지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;410&quot; data-start=&quot;359&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;나는 Git을 알고 있었던 걸까, 아니면 회사에서 하던 순서를 기억하고 있었던 걸까.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;wedevlops-github-6648895_1920.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btklGp/dJMcadcjDTr/Qvsm9IAYLRJN5Gb9mAXsWk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btklGp/dJMcadcjDTr/Qvsm9IAYLRJN5Gb9mAXsWk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btklGp/dJMcadcjDTr/Qvsm9IAYLRJN5Gb9mAXsWk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtklGp%2FdJMcadcjDTr%2FQvsm9IAYLRJN5Gb9mAXsWk%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;1920&quot; data-filename=&quot;wedevlops-github-6648895_1920.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1920&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-end=&quot;415&quot; data-start=&quot;412&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;449&quot; data-start=&quot;417&quot; data-section-id=&quot;4jwhdp&quot; data-ke-size=&quot;size23&quot;&gt;Git과 GitHub, 아주 간단하게 다시 이해했다&lt;/h3&gt;
&lt;p data-end=&quot;479&quot; data-start=&quot;451&quot; data-ke-size=&quot;size16&quot;&gt;둘을 거의 한 단어처럼 사용했지만 엄밀히는 다르다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;Git
&amp;rarr; 내 코드의 변경 이력을 관리하는 도구

GitHub
&amp;rarr; Git으로 관리하는 프로젝트를
   다른 사람과 공유할 수 있는 공간&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;605&quot; data-start=&quot;570&quot; data-ke-size=&quot;size16&quot;&gt;그리고 개발하면서 가장 많이 보게 될 흐름은 생각보다 단순하다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;내가 코드를 수정
      &amp;darr;
    add
      &amp;darr;
   commit
      &amp;darr;
내 PC의 Git 저장소
      &amp;darr;
    push
      &amp;darr;
    GitHub&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;761&quot; data-start=&quot;722&quot; data-ke-size=&quot;size16&quot;&gt;반대로 다른 사람이 작업한 내용을 가져올 때는 pull을 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;801&quot; data-start=&quot;763&quot; data-ke-size=&quot;size16&quot;&gt;이 정도 그림만 머릿속에 있어도 Git 명령어가 조금 덜 막연해진다.&lt;/p&gt;
&lt;hr data-end=&quot;806&quot; data-start=&quot;803&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;831&quot; data-start=&quot;808&quot; data-section-id=&quot;w0oxw&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;이번에는 clone부터 시작했다&lt;/span&gt;&lt;/h3&gt;
&lt;p data-end=&quot;887&quot; data-start=&quot;833&quot; data-ke-size=&quot;size16&quot;&gt;팀에서 GitHub Repository를 먼저 만들어두었기 때문에 나는 프로젝트를 가져오면 됐다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;git clone https://github.com/nocklock-h/wanted-ai-champ.git&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;981&quot; data-start=&quot;962&quot; data-ke-size=&quot;size16&quot;&gt;그리고 여기서 하나 다시 기억했다.&lt;/p&gt;
&lt;p data-end=&quot;1022&quot; data-start=&quot;983&quot; data-ke-size=&quot;size16&quot;&gt;clone은 그냥 &lt;b&gt;파일 다운로드&lt;/b&gt;라고 생각하면 조금 부족하다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;GitHub
   │
   │ clone
   ▼
내 PC의 Git Repository&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1156&quot; data-start=&quot;1086&quot; data-ke-size=&quot;size16&quot;&gt;소스뿐 아니라 Git이 관리하는 저장소와 이력까지 가져와서, 이제 내 PC에서도 같은 프로젝트의 개발을 이어갈 수 있게 된다.&lt;/p&gt;
&lt;hr data-end=&quot;1161&quot; data-start=&quot;1158&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1186&quot; data-start=&quot;1163&quot; data-section-id=&quot;1anff4t&quot; data-ke-size=&quot;size23&quot;&gt;그리고 역시 한 번에 되지는 않았다&lt;/h3&gt;
&lt;p data-end=&quot;1223&quot; data-start=&quot;1188&quot; data-ke-size=&quot;size16&quot;&gt;Git을 설치했는데 IntelliJ에서는 Git을 찾지 못했다.&lt;/p&gt;
&lt;p data-end=&quot;1276&quot; data-start=&quot;1225&quot; data-ke-size=&quot;size16&quot;&gt;Java는 17을 설치했는데 IntelliJ의 Gradle JVM은 22를 바라보고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1340&quot; data-start=&quot;1278&quot; data-ke-size=&quot;size16&quot;&gt;그걸 해결하고 Spring Boot를 실행했더니 이번에는 8080 포트를 이미 다른 프로그램이 사용하고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1383&quot; data-start=&quot;1342&quot; data-ke-size=&quot;size16&quot;&gt;포트를 확인해보니 예전에 사용하던 Oracle 관련 서비스가 잡고 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1412&quot; data-start=&quot;1385&quot; data-ke-size=&quot;size16&quot;&gt;결국 Spring Boot를 8081로 변경했다.&lt;/p&gt;
&lt;p data-end=&quot;1429&quot; data-start=&quot;1414&quot; data-ke-size=&quot;size16&quot;&gt;그런데 또 실행이 안 됐다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;server.port=8081&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1558&quot; data-start=&quot;1545&quot; data-ke-size=&quot;size16&quot;&gt;그리고 드디어 실행됐다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;Git
 &amp;darr;
GitHub Clone
 &amp;darr;
IntelliJ
 &amp;darr;
JDK 17
 &amp;darr;
Gradle
 &amp;darr;
Spring Boot
 &amp;darr;
localhost:8081&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1690&quot; data-start=&quot;1658&quot; data-ke-size=&quot;size16&quot;&gt;별것 아닌 환경설정인데 생각보다 여러 가지를 다시 만났다.&lt;/p&gt;
&lt;hr data-end=&quot;1695&quot; data-start=&quot;1692&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1711&quot; data-start=&quot;1697&quot; data-section-id=&quot;j8mgvl&quot; data-ke-size=&quot;size23&quot;&gt;오늘 다시 느낀 것&lt;/h3&gt;
&lt;p data-end=&quot;1756&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;예전에는 이런 문제가 생기면 빨리 해결하고 다음 업무로 넘어가는 게 중요했다.&lt;/p&gt;
&lt;p data-end=&quot;1777&quot; data-start=&quot;1758&quot; data-ke-size=&quot;size16&quot;&gt;지금은 조금 다르게 해보려고 한다.&lt;/p&gt;
&lt;p data-end=&quot;1896&quot; data-start=&quot;1779&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;왜 Git을 설치했는데 IntelliJ가 찾지 못했는지.&lt;br /&gt;왜 Java 17을 설치했는데 Gradle은 다른 Java를 보고 있었는지.&lt;br /&gt;왜 8080이라는 숫자 하나 때문에 서버가 실행되지 않았는지.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1917&quot; data-start=&quot;1898&quot; data-ke-size=&quot;size16&quot;&gt;하나씩 이해하면서 넘어가려고 한다.&lt;/p&gt;
&lt;p data-end=&quot;1930&quot; data-start=&quot;1919&quot; data-ke-size=&quot;size16&quot;&gt;Git도 마찬가지다.&lt;/p&gt;
&lt;p data-end=&quot;1969&quot; data-start=&quot;1932&quot; data-ke-size=&quot;size16&quot;&gt;명령어를 전부 외우는 것보다 우선 이것부터 제대로 이해하기로 했다.&lt;/p&gt;
&lt;blockquote data-end=&quot;2047&quot; data-start=&quot;1971&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;2047&quot; data-start=&quot;1973&quot; data-ke-size=&quot;size16&quot;&gt;clone으로 프로젝트를 가져오고,&lt;br /&gt;코드를 수정하고,&lt;br /&gt;commit으로 기록하고,&lt;br /&gt;push로 공유한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2073&quot; data-start=&quot;2049&quot; data-ke-size=&quot;size16&quot;&gt;오늘은 다시 개발하기 위한 환경을 만들었다.&lt;/p&gt;
&lt;p data-end=&quot;2107&quot; data-start=&quot;2075&quot; data-ke-size=&quot;size16&quot;&gt;다음부터는 이 빈 프로젝트에 실제 코드를 채워볼 생각이다.&lt;/p&gt;
&lt;p data-end=&quot;2138&quot; data-start=&quot;2109&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RE:개발자 #2&lt;/b&gt;&lt;br /&gt;Git을 다시 연결했다.&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;2168&quot; data-start=&quot;2140&quot; data-ke-size=&quot;size16&quot;&gt;그리고 생각보다, 다시 개발하는 기분이 조금 났다.&lt;/p&gt;</description>
      <category>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/2</guid>
      <comments>https://nocklock.tistory.com/2#entry2comment</comments>
      <pubDate>Wed, 16 Sep 2026 08:14:54 +0900</pubDate>
    </item>
    <item>
      <title>자바 개발자인데, 나는 정말 자바를 알고 있었을까? | RE:개발자 #1</title>
      <link>https://nocklock.tistory.com/1</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;AI와 다시 개발자가 되어가는 과정 #1&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;softradixtech-ai-generated-9241538_1920.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bP0zCF/dJMcadpWtE2/43s8XTPmKNyuAmatnev6I1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bP0zCF/dJMcadpWtE2/43s8XTPmKNyuAmatnev6I1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bP0zCF/dJMcadpWtE2/43s8XTPmKNyuAmatnev6I1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbP0zCF%2FdJMcadpWtE2%2F43s8XTPmKNyuAmatnev6I1%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; alt=&quot;개발자&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1314&quot; data-filename=&quot;softradixtech-ai-generated-9241538_1920.jpg&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1314&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;나는 약 2년 동안 자바 웹 개발자로 일했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Java, Spring MVC, JSP, jQuery, Ajax를 사용했고 PostgreSQL과 MySQL 같은 데이터베이스도 다뤘다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;실제로 운영되는 서비스를 개발했고, CRM 프로젝트에도 참여했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 적어도 나는 스스로를 &lt;/span&gt;&lt;b&gt;&lt;span&gt;'자바 개발자'​&lt;/span&gt;&lt;/b&gt;&lt;span&gt;라고 생각했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 오늘 기술 면접을 준비하면서 불편한 사실 하나를 마주하게 됐다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;나는 정말 자바 개발자인가?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;코드는 짤 수 있는데, 설명할 수 있을까?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;회사에서 개발할 때는 필요한 기능을 구현하면 됐다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Controller를 만들고 Service를 호출하고 DB에서 데이터를 가져와 화면에 뿌렸다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;SQL을 작성하고 Ajax로 데이터를 주고받았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;오류가 발생하면 로그를 보고 원인을 찾았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그렇게 프로젝트를 끝냈고 실제 서비스가 돌아갔다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;분명 개발을 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 기술 면접을 준비하면서 질문의 방향이 조금 달라졌다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;REST API가 무엇인가요?&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;HTTP 요청은 서버에서 어떻게 처리되나요?&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;트랜잭션은 왜 필요한가요?&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;인덱스를 사용하면 왜 조회가 빨라지나요?&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Spring Boot와 기존 Spring의 차이는 무엇인가요?&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;서비스를 처음부터 설계한다면 어떻게 구조를 잡겠습니까?&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;낯선 단어들은 아니었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;분명 들어봤고, 일부는 실제 업무에서도 사용했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 누군가에게 &lt;/span&gt;&lt;b&gt;&lt;span&gt;&quot;왜 그렇게 동작하는지 설명해보세요&quot;​&lt;/span&gt;&lt;/b&gt;&lt;span&gt;라고 하면 갑자기 말이 막혔다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그때 조금 뼈아픈 생각이 들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;나는 개발을 해온 것이 아니라, 어쩌면 개발하는 방법을 익혀온 것에 가까웠던 것은 아닐까.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;레거시 환경 탓만 할 수도 없었다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;내가 주로 사용했던 환경은 Spring MVC, JSP, jQuery 중심이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;최근 채용공고를 보면 Spring Boot, REST API, JPA, Docker, AWS 같은 단어들이 훨씬 많이 보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처음에는 단순히 기술 스택의 차이라고 생각했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;'나는 옛날 환경에서 일했으니까 아직 안 해본 것뿐이다.'&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;틀린 말은 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 그것만으로 설명되지 않는 부분도 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Spring Boot를 사용하지 않았더라도 Spring이 요청을 어떻게 처리하는지는 알아야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JPA를 사용하지 않았더라도 데이터베이스의 관계와 트랜잭션은 이해해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Docker를 사용하지 않았더라도 내가 만든 애플리케이션이 어떤 환경에서 실행되는지는 알아야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;REST API 프로젝트를 해보지 않았더라도 HTTP가 무엇인지는 설명할 수 있어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결국 문제는 최신 기술을 얼마나 많이 사용했느냐가 아니었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;기본기를 얼마나 제대로 이해하고 있었느냐였다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;모르는 것을 AI에게 물어보기 시작했다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 ChatGPT와 대화를 시작했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처음에는 단순한 면접 준비였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&quot;REST API 질문이 나오면 어떻게 대답하지?&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&quot;Spring Boot를 안 써봤다고 하면 불리할까?&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&quot;JPA 경험이 없으면 뭐라고 해야 하지?&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그런데 대화를 하다 보니 방향이 조금 달라졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;면접 답변만 외우는 건 별 의미가 없다는 생각이 들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;REST API의 정의를 외워서 면접에서 대답할 수는 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 직접 API 하나를 설계해보지 않는다면 결국 다음 면접에서도 비슷한 문제가 생긴다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 질문을 바꿨다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&quot;면접을 통과하려면 어떻게 대답해야 할까?&quot;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;가 아니라,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&quot;내가 다시 제대로 된 자바 백엔드 개발자가 되려면 어디서부터 시작해야 할까?&quot;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;AI에게 코드를 대신 짜달라고 하지 않기로 했다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI를 개발에 사용하는 방법에 대해서도 고민했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;ChatGPT에게 요구사항을 던지고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&quot;Spring Boot 프로젝트 만들어줘.&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;라고 하면 꽤 많은 코드를 만들어준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Controller도 만들어주고 Entity도 만들어주고 Repository도 만들어준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;복사해서 실행하면 어쩌면 정상적으로 동작할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 그렇게 하면 지금까지의 문제가 반복된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;동작하는 코드는 있는데 내가 설명하지 못하는 상태.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 이번에는 AI를 조금 다르게 사용해보기로 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI가 코드를 대신 만드는 것이 아니라,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;내가 이해하면서 만들 수 있도록 옆에서 계속 질문할 수 있는 페어 프로그래머처럼 사용해보기로 했다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 Spring Boot 프로젝트를 만들 때도 그냥 넘어가지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;왜 Java 21을 선택하는지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;왜 Maven 대신 Gradle을 선택했는지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Controller와 Service를 왜 분리하는지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Dependency Injection이 왜 필요한지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;HTTP 요청 하나가 들어오면 어디를 거쳐가는지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;DB Transaction은 어디에서 시작하고 끝나는지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;모르는 것이 나오면 그 자리에서 묻고, 직접 구현한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 가능하면 다시 내 말로 설명해본다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;내가 다시 공부해야 할 것들&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 내가 생각하는 로드맵은 이렇다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;Java&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;darr;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;객체지향 / JVM / Collection / Exception&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;darr;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;HTTP / Network&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;darr;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;Spring / Spring Boot&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;darr;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;REST API&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;darr;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;SQL / Database / Transaction / Index&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;darr;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;JPA&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;darr;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;Git&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;darr;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;Linux / Docker&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;darr;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;AWS&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;darr;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;테스트 / CI&amp;middot;CD&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;darr;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;시스템 설계&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 여기에서 끝내지 않을 생각이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;요즘 개발자가 AI를 무시할 수는 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;LLM이 무엇인지, 토큰은 무엇인지, API를 통해 어떻게 호출하는지, RAG는 무엇인지도 직접 작은 서비스를 만들면서 배워볼 생각이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;목표는 기술 이름을 많이 아는 개발자가 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;하나의 서비스를 처음부터 설계하고, 개발하고, 배포하고, 운영할 수 있는 개발자가 되는 것.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그게 이번 공부의 목표다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;그리고 모든 과정을 기록하기로 했다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예전에도 개발 공부를 시작한 적은 많았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;강의를 사고 몇 챕터 듣다가 멈추기도 했고, 새로운 기술이 보이면 또 다른 강의를 찾아보기도 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에는 방법을 조금 바꿔보려고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;공부한 내용을 정리하는 것이 아니라 &lt;/span&gt;&lt;b&gt;&lt;span&gt;공부하는 과정 자체를 기록하려고 한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;성공한 것만 쓰지 않을 생각이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;환경설정부터 기록한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;어떤 에러가 발생했는지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;왜 발생했는지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;ChatGPT가 처음에 어떤 해결책을 제시했는지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그 해결책이 틀렸다면 왜 틀렸는지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;검색해서 무엇을 추가로 확인했는지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 결국 내가 무엇을 이해했는지.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;전부 남겨보려고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 이 시리즈에는 아마 꽤 많은 삽질이 등장할 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;오히려 그게 이 기록의 핵심이라고 생각한다.&lt;/span&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;오늘이 0일 차다&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;오늘 기술면접을 준비하면서 내가 부족하다는 사실을 꽤 명확하게 확인했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기분 좋은 발견은 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 적어도 이제 무엇이 부족한지는 조금 알 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 한 가지는 확실히 정했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;경력이 몇 년인지보다 실제로 무엇을 이해하고 만들 수 있는 개발자인지가 더 중요하다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래서 다시 시작한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Java부터.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Spring Boot도 직접 설치해보고 REST API도 직접 만들어볼 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;DB를 설계하고 Docker에 올려보고 AWS에도 배포해볼 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AI도 단순히 코드를 대신 작성해주는 도구가 아니라 내가 더 빠르게 배우고 더 깊게 이해하기 위한 도구로 사용해볼 생각이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;몇 달 뒤 이 글을 다시 읽었을 때 지금보다 훨씬 많은 것을 설명할 수 있었으면 좋겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 가능하다면 그때는 자신 있게 말하고 싶다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;나는 자바 개발자다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div contenteditable=&quot;false&quot;&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;</description>
      <category>RE:개발자</category>
      <author>nocklock</author>
      <guid isPermaLink="true">https://nocklock.tistory.com/1</guid>
      <comments>https://nocklock.tistory.com/1#entry1comment</comments>
      <pubDate>Tue, 15 Sep 2026 14:55:34 +0900</pubDate>
    </item>
  </channel>
</rss>