<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>지속 가능한 꾸준함</title>
    <link>https://developer0hye.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sat, 20 Jun 2026 16:20:32 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>developer0hye</managingEditor>
    <item>
      <title>tistory blog polyfill.io 로그인 창 없애기</title>
      <link>https://developer0hye.tistory.com/938</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;564&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p8axI/dJMcafmxH2T/sfAQAMAN74HYjLajojuk8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p8axI/dJMcafmxH2T/sfAQAMAN74HYjLajojuk8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p8axI/dJMcafmxH2T/sfAQAMAN74HYjLajojuk8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp8axI%2FdJMcafmxH2T%2FsfAQAMAN74HYjLajojuk8K%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;564&quot; height=&quot;425&quot; data-origin-width=&quot;564&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;언제부터인가... 내 블로그 들어오는데 이런 게 떴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;해결 방법은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;681&quot; data-origin-height=&quot;541&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HjJfv/dJMcahkns9X/g0u318uak5gWOcYKul2so0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HjJfv/dJMcahkns9X/g0u318uak5gWOcYKul2so0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HjJfv/dJMcahkns9X/g0u318uak5gWOcYKul2so0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHjJfv%2FdJMcahkns9X%2Fg0u318uak5gWOcYKul2so0%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;681&quot; height=&quot;541&quot; data-origin-width=&quot;681&quot; data-origin-height=&quot;541&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;359&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZjUXI/dJMcaaestQu/12QcTugH2cRXUKkWp0IEB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZjUXI/dJMcaaestQu/12QcTugH2cRXUKkWp0IEB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZjUXI/dJMcaaestQu/12QcTugH2cRXUKkWp0IEB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZjUXI%2FdJMcaaestQu%2F12QcTugH2cRXUKkWp0IEB0%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;359&quot; height=&quot;342&quot; data-origin-width=&quot;359&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;1292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mjRwT/dJMcagsa9In/OvnQkHn7U55UZ4SdWGSabk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mjRwT/dJMcagsa9In/OvnQkHn7U55UZ4SdWGSabk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mjRwT/dJMcagsa9In/OvnQkHn7U55UZ4SdWGSabk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmjRwT%2FdJMcagsa9In%2FOvnQkHn7U55UZ4SdWGSabk%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;993&quot; height=&quot;1292&quot; data-origin-width=&quot;993&quot; data-origin-height=&quot;1292&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;845&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cti73K/dJMcaaestRC/UvBnLUt4rdOqBFfqKSCrN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cti73K/dJMcaaestRC/UvBnLUt4rdOqBFfqKSCrN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cti73K/dJMcaaestRC/UvBnLUt4rdOqBFfqKSCrN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcti73K%2FdJMcaaestRC%2FUvBnLUt4rdOqBFfqKSCrN0%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;1001&quot; height=&quot;845&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;845&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;lt;script&amp;nbsp;src=&quot;&lt;a href=&quot;https://polyfill.io/v3/polyfill.min.js?features=es6&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://polyfill.io/v3/polyfill.min.js?features=es6&lt;/a&gt;&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 라인을 찾아 지우고 적용을 눌렀더니 해결됐다.&lt;/p&gt;</description>
      <category>기타</category>
      <author>developer0hye</author>
      <guid isPermaLink="true">https://developer0hye.tistory.com/938</guid>
      <comments>https://developer0hye.tistory.com/938#entry938comment</comments>
      <pubDate>Tue, 2 Jun 2026 09:27:18 +0900</pubDate>
    </item>
    <item>
      <title>Windows Terminal, 새 탭을 현재 경로에서 열기 (Mac처럼)</title>
      <link>https://developer0hye.tistory.com/937</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Windows&amp;nbsp;Terminal은&amp;nbsp;새&amp;nbsp;탭(+)&amp;nbsp;버튼을&amp;nbsp;누르면&amp;nbsp;늘&amp;nbsp;홈&amp;nbsp;디렉터리(C:\Users\...)로&amp;nbsp;가버린다.&amp;nbsp;Mac&amp;nbsp;터미널처럼&amp;nbsp;지금&amp;nbsp;탭&amp;nbsp;경로&amp;nbsp;그대로&amp;nbsp;새&amp;nbsp;탭을&amp;nbsp;열고 &lt;br /&gt;&amp;nbsp;&amp;nbsp;싶다면&amp;nbsp;단축키&amp;nbsp;두&amp;nbsp;개면&amp;nbsp;끝이다. &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Ctrl&amp;nbsp;+&amp;nbsp;Shift&amp;nbsp;+&amp;nbsp;D&amp;nbsp;&amp;mdash;&amp;nbsp;현재&amp;nbsp;탭&amp;nbsp;경로&amp;nbsp;그대로&amp;nbsp;새&amp;nbsp;탭&amp;nbsp;열기 &lt;br /&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;Alt&amp;nbsp;+&amp;nbsp;Shift&amp;nbsp;+&amp;nbsp;D&amp;nbsp;&amp;mdash;&amp;nbsp;현재&amp;nbsp;경로로&amp;nbsp;패널&amp;nbsp;분할 &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&quot;+&quot;&amp;nbsp;버튼&amp;nbsp;자체는&amp;nbsp;현재&amp;nbsp;경로를&amp;nbsp;물려받지&amp;nbsp;못하니(항상&amp;nbsp;startingDirectory로&amp;nbsp;열림),&amp;nbsp;위&amp;nbsp;두&amp;nbsp;단축키를&amp;nbsp;쓰면&amp;nbsp;된다. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <author>developer0hye</author>
      <guid isPermaLink="true">https://developer0hye.tistory.com/937</guid>
      <comments>https://developer0hye.tistory.com/937#entry937comment</comments>
      <pubDate>Mon, 1 Jun 2026 20:18:07 +0900</pubDate>
    </item>
    <item>
      <title>맥os 스크린샷 프로세스 종료 명령어</title>
      <link>https://developer0hye.tistory.com/936</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;killall&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span&gt;screencaptureui&lt;/span&gt;&lt;/p&gt;</description>
      <category>기타</category>
      <author>developer0hye</author>
      <guid isPermaLink="true">https://developer0hye.tistory.com/936</guid>
      <comments>https://developer0hye.tistory.com/936#entry936comment</comments>
      <pubDate>Tue, 12 May 2026 23:12:06 +0900</pubDate>
    </item>
    <item>
      <title>Ubuntu에서 Duck DNS로 Dynamic DNS 설정하기 (SSH 외부 접속)</title>
      <link>https://developer0hye.tistory.com/935</link>
      <description>&lt;h1&gt;Ubuntu에서 Duck DNS로 Dynamic DNS 설정하기 (SSH 외부 접속)&lt;/h1&gt;
&lt;p&gt;ISP에서 유동 IP를 사용하는 환경에서도 도메인으로 항상 SSH 접속이 가능하도록 Duck DNS를 설정하는 방법을 정리합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Dynamic DNS(DDNS)란?&lt;/h2&gt;
&lt;p&gt;ISP가 공인 IP를 주기적으로 변경하는 환경에서, 도메인 이름을 항상 현재 IP에 자동으로 매핑해주는 서비스입니다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ 문제 상황 ]
월요일: 118.37.94.241  →  ssh user@118.37.94.241 ✅
화요일: IP 변경됨!      →  ssh user@118.37.94.241 ❌ 접속 불가

[ DDNS 적용 후 ]
ssh user@mypc.duckdns.org  →  IP가 바뀌어도 항상 접속 가능 ✅&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;동작 원리&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;┌─────────┐    5분마다 IP 전송     ┌───────────┐
│  내 PC   │ ──────────────────→  │ Duck DNS  │
│          │  &amp;quot;내 IP는 지금       │  서버      │
│          │   xxx.xxx.xxx.xxx&amp;quot;  │           │
└─────────┘                       └───────────┘
                                       │
                                       │ DNS 응답
                                       ▼
┌─────────┐  mypc.duckdns.org       ┌───────────┐
│ 외부 PC  │ ──── DNS 질의 ────→    │ Duck DNS  │
│          │ ←── xxx.xxx.xxx.xxx ── │  서버      │
│          │                        └───────────┘
│          │  ssh xxx.xxx.xxx.xxx:22
│          │ ──────────────────────→  내 PC에 접속
└─────────┘&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2&gt;환경&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu 24.04 LTS&lt;/li&gt;
&lt;li&gt;SSH 서버 설치 및 실행 중 (&lt;code&gt;openssh-server&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SSH 서버가 없다면 먼저 설치합니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo apt install openssh-server -y
sudo systemctl enable --now sshd&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;1. Duck DNS 도메인 등록&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.duckdns.org&quot;&gt;https://www.duckdns.org&lt;/a&gt; 접속&lt;/li&gt;
&lt;li&gt;GitHub, Google 등으로 로그인&lt;/li&gt;
&lt;li&gt;원하는 서브도메인 입력 (예: &lt;code&gt;mypc&lt;/code&gt;) → &lt;strong&gt;add domain&lt;/strong&gt; 클릭&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mypc.duckdns.org&lt;/code&gt; 도메인이 생성됨&lt;/li&gt;
&lt;li&gt;페이지 상단의 &lt;strong&gt;token&lt;/strong&gt;을 복사해둡니다&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;2. IP 자동 갱신 스크립트 생성&lt;/h2&gt;
&lt;p&gt;Duck DNS에 현재 IP를 주기적으로 알려주는 스크립트를 만듭니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mkdir -p ~/duckdns&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;nano ~/duckdns/duck.sh&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;아래 내용을 작성합니다. &lt;code&gt;내도메인&lt;/code&gt;과 &lt;code&gt;내토큰&lt;/code&gt;을 본인 것으로 변경하세요.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;#!/bin/bash
echo url=&amp;quot;https://www.duckdns.org/update?domains=내도메인&amp;amp;token=내토큰&amp;amp;ip=&amp;quot; | curl -k -o ~/duckdns/duck.log -K -&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;예를 들어 도메인이 &lt;code&gt;mypc&lt;/code&gt;, 토큰이 &lt;code&gt;abcd1234-5678-efgh&lt;/code&gt;라면:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;#!/bin/bash
echo url=&amp;quot;https://www.duckdns.org/update?domains=mypc&amp;amp;token=abcd1234-5678-efgh&amp;amp;ip=&amp;quot; | curl -k -o ~/duckdns/duck.log -K -&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;실행 권한을 부여합니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;chmod 700 ~/duckdns/duck.sh&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;3. 테스트 실행&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;~/duckdns/duck.sh
cat ~/duckdns/duck.log&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;OK&lt;/code&gt;가 출력되면 성공입니다. &lt;code&gt;KO&lt;/code&gt;가 출력되면 도메인이나 토큰을 다시 확인하세요.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;4. Cron으로 자동 실행 등록&lt;/h2&gt;
&lt;p&gt;5분마다 자동으로 IP를 갱신하도록 cron에 등록합니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;crontab -e&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;맨 아래에 다음 줄을 추가합니다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*/5 * * * * ~/duckdns/duck.sh &amp;gt;/dev/null 2&amp;gt;&amp;amp;1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;저장 후 등록 확인:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;crontab -l&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;5. 외부에서 접속 확인&lt;/h2&gt;
&lt;p&gt;외부 PC에서 아래 명령어로 접속합니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ssh 유저이름@내도메인.duckdns.org&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;비밀번호를 입력하면 접속됩니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;6. 보안 설정 (권장)&lt;/h2&gt;
&lt;p&gt;공인 IP에 SSH가 노출되면 봇들의 무차별 로그인 시도가 들어옵니다. 실제로 하루에 수천 건이 발생할 수 있습니다. 아래 보안 설정을 권장합니다.&lt;/p&gt;
&lt;h3&gt;fail2ban 설치&lt;/h3&gt;
&lt;p&gt;비밀번호를 여러 번 틀리는 IP를 자동 차단합니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo apt install fail2ban -y&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;SSH 키 인증 설정&lt;/h3&gt;
&lt;p&gt;외부 PC에서 실행:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ssh-keygen -t ed25519
ssh-copy-id 유저이름@내도메인.duckdns.org&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;비밀번호 로그인 비활성화&lt;/h3&gt;
&lt;p&gt;키 등록이 완료된 후, 서버에서 실행:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo nano /etc/ssh/sshd_config&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;아래 항목을 변경합니다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PasswordAuthentication no&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;SSH 재시작:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo systemctl restart sshd&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이후 SSH 키가 없는 사람은 비밀번호를 알아도 로그인이 불가능합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;요약&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;단계&lt;/th&gt;
&lt;th&gt;내용&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Duck DNS 가입&lt;/td&gt;
&lt;td&gt;도메인 등록 + 토큰 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;스크립트 생성&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~/duckdns/duck.sh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cron 등록&lt;/td&gt;
&lt;td&gt;5분마다 IP 자동 갱신&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;보안 설정&lt;/td&gt;
&lt;td&gt;fail2ban + SSH 키 인증 + 비밀번호 로그인 차단&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;무료이고 설정도 간단해서 개인 서버 용도로 추천합니다.&lt;/p&gt;</description>
      <category>기타</category>
      <author>developer0hye</author>
      <guid isPermaLink="true">https://developer0hye.tistory.com/935</guid>
      <comments>https://developer0hye.tistory.com/935#entry935comment</comments>
      <pubDate>Fri, 3 Apr 2026 19:51:53 +0900</pubDate>
    </item>
    <item>
      <title>Headless 서버에서 GWS CLI 인증하기</title>
      <link>https://developer0hye.tistory.com/934</link>
      <description>&lt;h1&gt;Headless 서버에서 GWS CLI 인증하기&lt;/h1&gt;
&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;gws auth login&lt;/code&gt;은 OAuth 인증을 사용한다. 인증 흐름은 다음과 같다:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;서버에서 &lt;code&gt;gws auth login&lt;/code&gt; 실행 → 임시 HTTP 서버를 &lt;code&gt;localhost:{PORT}&lt;/code&gt;에 띄우고 대기&lt;/li&gt;
&lt;li&gt;출력된 URL을 브라우저에서 열고 Google 로그인&lt;/li&gt;
&lt;li&gt;Google이 &lt;code&gt;http://localhost:{PORT}&lt;/code&gt;로 리다이렉트하여 인증 코드 전달&lt;/li&gt;
&lt;li&gt;gws가 코드를 수신하여 인증 완료&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Headless 서버에는 브라우저가 없으므로 데스크탑 브라우저를 사용해야 하는데, 인증 후 리다이렉트되는 &lt;code&gt;localhost&lt;/code&gt;가 &lt;strong&gt;데스크탑의 localhost&lt;/strong&gt;를 가리키게 되어 서버의 gws가 콜백을 받지 못한다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;데스크탑 브라우저 → Google 인증 → redirect to localhost:{PORT}
                                        ↓
                                 데스크탑의 localhost (아무것도 없음) ❌
                                 서버의 localhost (gws 대기 중) — 도달 불가&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;해결: SSH 포트 포워딩&lt;/h2&gt;
&lt;p&gt;SSH 터널을 이용해 데스크탑의 &lt;code&gt;localhost:{PORT}&lt;/code&gt;를 서버의 &lt;code&gt;localhost:{PORT}&lt;/code&gt;로 연결한다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;데스크탑 브라우저 → Google 인증 → redirect to localhost:{PORT}
                                        ↓
                                 데스크탑의 localhost:{PORT}
                                        ↓  (SSH 터널)
                                 서버의 localhost:{PORT} (gws 대기 중) ✅&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;순서&lt;/h2&gt;
&lt;h3&gt;1. 서버에서 &lt;code&gt;gws auth login&lt;/code&gt; 실행&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ gws auth login
Open this URL in your browser to authenticate:

  https://accounts.google.com/o/oauth2/auth?...&amp;amp;redirect_uri=http://localhost:12345&amp;amp;...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;URL에서 &lt;strong&gt;포트 번호를 확인&lt;/strong&gt;한다 (위 예시에서 &lt;code&gt;12345&lt;/code&gt;). 포트는 매 실행마다 바뀐다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 상태에서 터미널을 닫지 말고 대기한다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h3&gt;2. 데스크탑에서 SSH 터널 열기&lt;/h3&gt;
&lt;p&gt;새 터미널을 열고 SSH 터널을 설정한다. 포트 번호를 1단계에서 확인한 값으로 교체한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ssh -L {PORT}:localhost:{PORT} {서버} -N&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;예시:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;ssh -L 12345:localhost:12345 user@your-server -N&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;옵션&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-L {PORT}:localhost:{PORT}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;데스크탑의 PORT를 서버의 localhost:PORT로 포워딩&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-N&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;원격 명령 실행 없이 터널만 유지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;(선택) 백그라운드로 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;3. 데스크탑 브라우저에서 인증&lt;/h3&gt;
&lt;p&gt;1단계에서 출력된 URL을 데스크탑 브라우저에 붙여넣고 Google 계정으로 로그인한다.&lt;/p&gt;
&lt;p&gt;인증이 완료되면 &lt;code&gt;localhost:{PORT}&lt;/code&gt;로 리다이렉트되고, SSH 터널을 통해 서버의 gws가 콜백을 수신하여 인증이 완료된다.&lt;/p&gt;
&lt;h3&gt;4. 정리&lt;/h3&gt;
&lt;p&gt;인증 완료 후 SSH 터널 터미널을 &lt;code&gt;Ctrl+C&lt;/code&gt;로 종료한다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-f&lt;/code&gt; 옵션으로 백그라운드 실행했을 경우:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 터널 프로세스 찾기
ps aux | grep &amp;quot;ssh -L&amp;quot;

# 종료
kill {PID}&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;요약&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 1. 서버에서 실행 (포트 확인 후 대기)
gws auth login

# 2. 데스크탑에서 SSH 터널 (포트 번호 맞춰서)
ssh -L 12345:localhost:12345 user@your-server -N

# 3. 데스크탑 브라우저에서 URL 열어 인증&lt;/code&gt;&lt;/pre&gt;</description>
      <category>기타</category>
      <author>developer0hye</author>
      <guid isPermaLink="true">https://developer0hye.tistory.com/934</guid>
      <comments>https://developer0hye.tistory.com/934#entry934comment</comments>
      <pubDate>Thu, 2 Apr 2026 16:42:52 +0900</pubDate>
    </item>
    <item>
      <title>rf detr contribution!</title>
      <link>https://developer0hye.tistory.com/933</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/roboflow/rf-detr/pull/167#event-23855087076&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/roboflow/rf-detr/pull/167#event-23855087076&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1774364476383&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Enhance WindowedDinov2 input validation and fix tensor reshaping by developer0hye &amp;middot; Pull Request #167 &amp;middot; roboflow/rf-detr&quot; data-og-description=&quot;Description Harden WindowedDinov2 input validation: replace the strippable assert with an explicit raise ValueError so the spatial-dimension check is always active (even under Python -O). No tensor...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/roboflow/rf-detr/pull/167#event-23855087076&quot; data-og-url=&quot;https://github.com/roboflow/rf-detr/pull/167&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bivoVH/dJMb83SimzV/kddpb09geXpkOmcaM9MKA0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/xnYd5/dJMb9iaQFS8/LKMTGvORVtjnNrZJF0NkdK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/roboflow/rf-detr/pull/167#event-23855087076&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/roboflow/rf-detr/pull/167#event-23855087076&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bivoVH/dJMb83SimzV/kddpb09geXpkOmcaM9MKA0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/xnYd5/dJMb9iaQFS8/LKMTGvORVtjnNrZJF0NkdK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Enhance WindowedDinov2 input validation and fix tensor reshaping by developer0hye &amp;middot; Pull Request #167 &amp;middot; roboflow/rf-detr&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Description Harden WindowedDinov2 input validation: replace the strippable assert with an explicit raise ValueError so the spatial-dimension check is always active (even under Python -O). No tensor...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1년 전쯤 올린건데 이제 검토하고 머지됐다. 잘 기억도 안나네&lt;/p&gt;</description>
      <category>Contribution 일지</category>
      <author>developer0hye</author>
      <guid isPermaLink="true">https://developer0hye.tistory.com/933</guid>
      <comments>https://developer0hye.tistory.com/933#entry933comment</comments>
      <pubDate>Wed, 25 Mar 2026 00:01:44 +0900</pubDate>
    </item>
    <item>
      <title>클로드코드 max 플랜 200달러 후기</title>
      <link>https://developer0hye.tistory.com/932</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;ralph 같은 거로 며칠 내내 자동으로 돌아가게 하면 내 프로젝트 기준 3~4일 정도면 100% 찼고, 내가 수동으로 다 보면서 결정하고 진행시키면 한 일주일에 주간 한도량 기준 50~60% 쓴다.&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;a href=&quot;https://github.com/developer0hye&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/developer0hye&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1774261391508&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;profile&quot; data-og-title=&quot;developer0hye - Overview&quot; data-og-description=&quot;practical. developer0hye has 257 repositories available. Follow their code on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/developer0hye&quot; data-og-url=&quot;https://github.com/developer0hye&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cPpxJw/dJMb9lMaWPx/aSQBEAgKNWn05CKPR8nje0/img.png?width=300&amp;amp;height=300&amp;amp;face=129_127_175_178,https://scrap.kakaocdn.net/dn/MyYp0/dJMb9lk6y9P/j2PUxjvkm5FCDnvy0pp6AK/img.png?width=300&amp;amp;height=300&amp;amp;face=129_127_175_178&quot;&gt;&lt;a href=&quot;https://github.com/developer0hye&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/developer0hye&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cPpxJw/dJMb9lMaWPx/aSQBEAgKNWn05CKPR8nje0/img.png?width=300&amp;amp;height=300&amp;amp;face=129_127_175_178,https://scrap.kakaocdn.net/dn/MyYp0/dJMb9lk6y9P/j2PUxjvkm5FCDnvy0pp6AK/img.png?width=300&amp;amp;height=300&amp;amp;face=129_127_175_178');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;developer0hye - Overview&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;practical. developer0hye has 257 repositories available. Follow their code on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;br /&gt;&lt;br /&gt;회사거는 못올리기에~ 위 계정의 작업량이랑 비슷하거나 그 이상이라고 보면 됨&lt;/p&gt;</description>
      <category>인생</category>
      <author>developer0hye</author>
      <guid isPermaLink="true">https://developer0hye.tistory.com/932</guid>
      <comments>https://developer0hye.tistory.com/932#entry932comment</comments>
      <pubDate>Mon, 23 Mar 2026 19:24:09 +0900</pubDate>
    </item>
    <item>
      <title>특정 코어를 특정 프로세스에 할당하여 처리하는 방법 CPU Affinity: taskset과 start /affinity</title>
      <link>https://developer0hye.tistory.com/931</link>
      <description>&lt;p&gt;아직 안 써봄. Claude랑 대화하다가 말해줘서 나중에 써먹을 일 있을 거 같아서 정리해놓음&lt;/p&gt;
&lt;h2&gt;CPU Affinity란?&lt;/h2&gt;
&lt;p&gt;프로세스가 실행될 CPU 코어를 지정하는 기능이다. 기본적으로 OS 스케줄러는 프로세스를 여러 코어에 자유롭게 옮겨가며 실행하는데, CPU Affinity를 설정하면 특정 코어에서만 실행되도록 고정할 수 있다.&lt;/p&gt;
&lt;h2&gt;왜 필요한가?&lt;/h2&gt;
&lt;h3&gt;1. 캐시 친화성 (Cache Affinity)&lt;/h3&gt;
&lt;p&gt;CPU 코어마다 L1/L2 캐시를 별도로 갖고 있다. 프로세스가 코어 0에서 실행되다가 코어 3으로 옮겨지면, 코어 0의 캐시에 쌓아둔 데이터를 코어 3에서 다시 로드해야 한다 (cold cache). 코어를 고정하면 캐시가 warm 상태로 유지되어 성능이 안정적이다.&lt;/p&gt;
&lt;h3&gt;2. NUMA 최적화&lt;/h3&gt;
&lt;p&gt;멀티소켓 서버에서는 각 CPU 소켓이 자기 근처의 메모리에 빠르게 접근할 수 있지만, 다른 소켓의 메모리에 접근하면 2~3배 느리다 (원격 메모리 접근). CPU Affinity로 프로세스를 특정 소켓의 코어에 고정하면 항상 로컬 메모리만 접근하게 할 수 있다.&lt;/p&gt;
&lt;h3&gt;3. Jitter 감소&lt;/h3&gt;
&lt;p&gt;코어 간 마이그레이션에는 비용이 든다. 실시간 처리나 벤치마크처럼 일관된 응답 시간이 중요한 상황에서 코어를 고정하면 레이턴시 변동(jitter)을 줄일 수 있다.&lt;/p&gt;
&lt;h2&gt;Linux: taskset&lt;/h2&gt;
&lt;h3&gt;기본 사용법&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 프로세스를 코어 2에서 실행
taskset -c 2 ./my_program

# 코어 0, 1, 2에서 실행
taskset -c 0-2 ./my_program

# 코어 0과 4에서 실행
taskset -c 0,4 ./my_program&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;실행 중인 프로세스에 적용&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# PID 확인
pidof my_program

# 해당 프로세스를 코어 3에 고정
taskset -pc 3 &amp;lt;PID&amp;gt;

# 현재 affinity 확인
taskset -pc &amp;lt;PID&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;CPU 마스크 방식&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;-c&lt;/code&gt; 옵션 대신 비트마스크로 지정할 수도 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 0x1 = 0001 = 코어 0
taskset 0x1 ./my_program

# 0x5 = 0101 = 코어 0, 2
taskset 0x5 ./my_program

# 0xF = 1111 = 코어 0, 1, 2, 3
taskset 0xF ./my_program&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;벤치마크 예시&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# turbo boost 비활성화 (클럭 변동 제거)
echo 1 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo

# CPU governor를 performance로 고정
sudo cpupower frequency-set -g performance

# 코어 2에 고정하여 벤치마크 실행
taskset -c 2 cargo bench&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Windows: start /affinity&lt;/h2&gt;
&lt;h3&gt;기본 사용법&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;start /affinity &amp;lt;hex_mask&amp;gt; &amp;lt;program&amp;gt;&lt;/code&gt; 형식으로 사용한다. 마스크는 16진수 비트마스크다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;# 코어 0 (0x1 = 0001)
start /affinity 0x1 my_program.exe

# 코어 1 (0x2 = 0010)
start /affinity 0x2 my_program.exe

# 코어 0, 1 (0x3 = 0011)
start /affinity 0x3 my_program.exe

# 코어 0, 2 (0x5 = 0101)
start /affinity 0x5 my_program.exe&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;비트마스크 빠른 참조표&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;마스크&lt;/th&gt;
&lt;th&gt;이진수&lt;/th&gt;
&lt;th&gt;사용 코어&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;0x1&lt;/td&gt;
&lt;td&gt;0001&lt;/td&gt;
&lt;td&gt;코어 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x2&lt;/td&gt;
&lt;td&gt;0010&lt;/td&gt;
&lt;td&gt;코어 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x4&lt;/td&gt;
&lt;td&gt;0100&lt;/td&gt;
&lt;td&gt;코어 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x3&lt;/td&gt;
&lt;td&gt;0011&lt;/td&gt;
&lt;td&gt;코어 0, 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x5&lt;/td&gt;
&lt;td&gt;0101&lt;/td&gt;
&lt;td&gt;코어 0, 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0xF&lt;/td&gt;
&lt;td&gt;1111&lt;/td&gt;
&lt;td&gt;코어 0~3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0xFF&lt;/td&gt;
&lt;td&gt;11111111&lt;/td&gt;
&lt;td&gt;코어 0~7&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;PowerShell에서 실행 중인 프로세스에 적용&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;# 프로세스의 affinity를 코어 0, 1로 변경
$proc = Get-Process -Name &amp;quot;my_program&amp;quot;
$proc.ProcessorAffinity = 0x3&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;실제 서비스에서의 활용 사례&lt;/h2&gt;
&lt;h3&gt;NGINX&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-nginx&quot;&gt;# nginx.conf
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
# worker 0 → 코어 0, worker 1 → 코어 1, ...&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Redis&lt;/h3&gt;
&lt;p&gt;Redis는 싱글스레드 기반이라 하나의 코어에 고정하면 효과적이다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;taskset -c 0 redis-server /etc/redis/redis.conf&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;systemd 서비스&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;# /etc/systemd/system/my_service.service
[Service]
ExecStart=/usr/bin/my_program
CPUAffinity=0 1 2 3&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;주의사항&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;무조건 좋은 건 아니다.&lt;/strong&gt; OS 스케줄러는 대부분의 상황에서 충분히 잘 동작한다. CPU Affinity는 레이턴시에 극도로 민감한 서비스(실시간 처리, 금융 트레이딩, 고성능 네트워크)에서 진가를 발휘한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;코어 배분을 잘못하면 역효과.&lt;/strong&gt; 특정 코어만 과부하 걸리고 나머지 코어는 놀게 될 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;하이퍼스레딩 주의.&lt;/strong&gt; 물리 코어와 논리 코어를 구분해야 한다. 같은 물리 코어의 두 논리 코어에 고정하면 리소스를 나눠 쓰게 되어 기대만큼 성능이 안 나올 수 있다. &lt;code&gt;lscpu&lt;/code&gt;로 토폴로지를 확인하자.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>기타</category>
      <author>developer0hye</author>
      <guid isPermaLink="true">https://developer0hye.tistory.com/931</guid>
      <comments>https://developer0hye.tistory.com/931#entry931comment</comments>
      <pubDate>Mon, 23 Mar 2026 10:48:04 +0900</pubDate>
    </item>
    <item>
      <title>huggingface candle conv2d 연산 오류 fix 기여!</title>
      <link>https://developer0hye.tistory.com/930</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;998&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bl8Gtx/dJMcagESKpb/kcZA2d6OIBnd99Vq0TIdKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bl8Gtx/dJMcagESKpb/kcZA2d6OIBnd99Vq0TIdKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bl8Gtx/dJMcagESKpb/kcZA2d6OIBnd99Vq0TIdKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbl8Gtx%2FdJMcagESKpb%2FkcZA2d6OIBnd99Vq0TIdKK%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;1920&quot; height=&quot;998&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;998&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cool&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;a href=&quot;https://github.com/huggingface/candle/pull/3405&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/huggingface/candle/pull/3405&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1774182020629&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;fix: conv2d_tiled produces wrong results when C == H == W by developer0hye &amp;middot; Pull Request #3405 &amp;middot; huggingface/candle&quot; data-og-description=&quot;Bug conv2d_tiled produces completely wrong output when C_in == H == W (e.g., input shape [1, 64, 64, 64]). Fixes #3404 Root Cause conv2d_tiled converts input from NCHW to NHWC internally. It uses a...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/huggingface/candle/pull/3405&quot; data-og-url=&quot;https://github.com/huggingface/candle/pull/3405&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/rgNoI/dJMb9b3Roc4/n9EwzQwW0DCvSSItIN2uBk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bFEwzT/dJMb9b3Roc3/314laiZBN9MHP6NkJOoUYK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/huggingface/candle/pull/3405&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/huggingface/candle/pull/3405&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/rgNoI/dJMb9b3Roc4/n9EwzQwW0DCvSSItIN2uBk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bFEwzT/dJMb9b3Roc3/314laiZBN9MHP6NkJOoUYK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;fix: conv2d_tiled produces wrong results when C == H == W by developer0hye &amp;middot; Pull Request #3405 &amp;middot; huggingface/candle&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Bug conv2d_tiled produces completely wrong output when C_in == H == W (e.g., input shape [1, 64, 64, 64]). Fixes #3404 Root Cause conv2d_tiled converts input from NCHW to NHWC internally. It uses a...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거 다 클로드로 한거다.&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;/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;pr 에 description 그 누가 읽어도 납득가게 쓰라고 하고, merged pr 참고해서 description 톤, 방식 지키라고하고 또 repo내에 contribution guide, code formatting guide 있으면 따르라고 말함. 또 이런 건 엄밀하게 정의되는 test case가 있어야하니 test case 설계잘하라고 시킴&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;a href=&quot;https://github.com/developer0hye/candle-birefnet&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/developer0hye/candle-birefnet&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1774182161226&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - developer0hye/candle-birefnet: BiRefNet inference for Hugging Face Candle&quot; data-og-description=&quot;BiRefNet inference for Hugging Face Candle. Contribute to developer0hye/candle-birefnet development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/developer0hye/candle-birefnet&quot; data-og-url=&quot;https://github.com/developer0hye/candle-birefnet&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bWaeTR/dJMb8SXw6tx/wl0vTw1MzaYBHVAZe0y8n0/img.png?width=1200&amp;amp;height=600&amp;amp;face=1001_157_1042_202,https://scrap.kakaocdn.net/dn/3OLFA/dJMb8TB8VLI/R1WwO0e8NxiQscKQT8Dgu0/img.png?width=1200&amp;amp;height=600&amp;amp;face=1001_157_1042_202,https://scrap.kakaocdn.net/dn/bTcWQh/dJMb8YXKPuU/SS9A3FhtuRzd8a8IYvKChk/img.png?width=3072&amp;amp;height=1024&amp;amp;face=0_0_3072_1024&quot;&gt;&lt;a href=&quot;https://github.com/developer0hye/candle-birefnet&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/developer0hye/candle-birefnet&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bWaeTR/dJMb8SXw6tx/wl0vTw1MzaYBHVAZe0y8n0/img.png?width=1200&amp;amp;height=600&amp;amp;face=1001_157_1042_202,https://scrap.kakaocdn.net/dn/3OLFA/dJMb8TB8VLI/R1WwO0e8NxiQscKQT8Dgu0/img.png?width=1200&amp;amp;height=600&amp;amp;face=1001_157_1042_202,https://scrap.kakaocdn.net/dn/bTcWQh/dJMb8YXKPuU/SS9A3FhtuRzd8a8IYvKChk/img.png?width=3072&amp;amp;height=1024&amp;amp;face=0_0_3072_1024');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - developer0hye/candle-birefnet: BiRefNet inference for Hugging Face Candle&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;BiRefNet inference for Hugging Face Candle. Contribute to developer0hye/candle-birefnet development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거 구현하다가 발견한 문제였다.&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;아무리 요새 linear, attention layer 가 크게 중요하다고 하지만 vision 분야의 근본 연산인 conv연산에 오류가 있다니!! 말이 안 되지 않는가. 이렇게 오픈소스는 에러가 많고 기여할 여지가 굉장히 많다.&lt;/p&gt;</description>
      <category>Deep Learning</category>
      <author>developer0hye</author>
      <guid isPermaLink="true">https://developer0hye.tistory.com/930</guid>
      <comments>https://developer0hye.tistory.com/930#entry930comment</comments>
      <pubDate>Sun, 22 Mar 2026 21:24:11 +0900</pubDate>
    </item>
    <item>
      <title>마크다운을 정보 유출 걱정 없이 PDF로 변환하는 가장 쉬운 방법 (무료, 설치 없음, 서버 파일 업로드 없음)</title>
      <link>https://developer0hye.tistory.com/929</link>
      <description>&lt;p&gt;마크다운(Markdown) 파일을 PDF로 변환해야 할 때, 어떤 방법을 쓰시나요?&lt;/p&gt;
&lt;p&gt;Pandoc 설치? 너무 번거롭습니다.&lt;br&gt;온라인 변환 사이트? 내 파일을 서버에 올려야 해서 불안합니다.&lt;br&gt;VS Code 확장? 설정이 복잡합니다.&lt;/p&gt;
&lt;p&gt;오늘 소개할 도구는 이 모든 문제를 한 번에 해결합니다.&lt;/p&gt;
&lt;h2&gt;소개: dontsendfile.com/md2pdf&lt;/h2&gt;
&lt;p&gt;  &lt;a href=&quot;https://dontsendfile.com/md2pdf&quot;&gt;https://dontsendfile.com/md2pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;이름 그대로, 파일을 어디에도 보내지 않는 마크다운 → PDF 변환기입니다.&lt;/p&gt;
&lt;p&gt;핵심 특징을 정리하면:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ 100% 브라우저에서 동작 — 파일이 서버로 전송되지 않음&lt;/li&gt;
&lt;li&gt;✅ 완전 무료, 회원가입 없음, 워터마크 없음&lt;/li&gt;
&lt;li&gt;✅ 설치할 것 없음 — 브라우저만 있으면 됨&lt;/li&gt;
&lt;li&gt;✅ Mermaid 다이어그램, LaTeX 수식 지원&lt;/li&gt;
&lt;li&gt;✅ GitHub 저장소 URL만 붙여넣으면 README를 바로 PDF로 변환&lt;/li&gt;
&lt;li&gt;✅ 여러 파일 한꺼번에 일괄 변환 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;왜 이 도구인가? — 기존 방법과 비교&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;방법&lt;/th&gt;
&lt;th&gt;설치 필요&lt;/th&gt;
&lt;th&gt;파일 업로드&lt;/th&gt;
&lt;th&gt;Mermaid/수식&lt;/th&gt;
&lt;th&gt;무료&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Pandoc&lt;/td&gt;
&lt;td&gt;O (CLI 설치)&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;플러그인 필요&lt;/td&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;온라인 변환 사이트&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;O (서버 전송)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;대부분 미지원&lt;/td&gt;
&lt;td&gt;일부 유료&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VS Code 확장&lt;/td&gt;
&lt;td&gt;O (확장 설치)&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;설정 복잡&lt;/td&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;dontsendfile.com&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;X (로컬 처리)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;기본 지원&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;O&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;회사 내부 문서, 이력서, 기술 문서처럼 민감한 파일을 다룰 때 특히 유용합니다. 파일이 내 브라우저를 절대 벗어나지 않으니까요.&lt;/p&gt;
&lt;h2&gt;사용법 — 3단계면 끝&lt;/h2&gt;
&lt;h3&gt;1단계: 파일 선택&lt;/h3&gt;
&lt;p&gt;세 가지 방법 중 하나를 고르세요:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;파일 선택&lt;/strong&gt;: .md 파일을 직접 선택&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;폴더 업로드&lt;/strong&gt;: 이미지가 포함된 폴더를 통째로 업로드 (이미지 경로 자동 해석)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub URL 붙여넣기&lt;/strong&gt;: 공개 저장소 URL을 입력하면 모든 마크다운 파일을 자동으로 불러옴&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2단계: 미리보기 확인&lt;/h3&gt;
&lt;p&gt;GitHub 스타일로 렌더링된 미리보기를 확인합니다. Mermaid 다이어그램이나 수식이 있으면 자동으로 렌더링됩니다.&lt;/p&gt;
&lt;h3&gt;3단계: PDF 저장&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Save as PDF&lt;/strong&gt;: 현재 보고 있는 파일 하나를 PDF로 저장&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Save All&lt;/strong&gt;: 체크한 파일 전체를 한꺼번에 PDF로 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;이런 분들에게 추천합니다&lt;/h2&gt;
&lt;h3&gt;개발자&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;GitHub README, 기술 문서를 PDF로 만들어 공유해야 할 때&lt;/li&gt;
&lt;li&gt;오픈소스 프로젝트 문서를 오프라인용으로 저장할 때&lt;/li&gt;
&lt;li&gt;PR 리뷰 자료를 PDF로 뽑아야 할 때&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;학생 / 연구자&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;LaTeX 수식이 포함된 마크다운 노트를 PDF로 변환할 때&lt;/li&gt;
&lt;li&gt;논문 초안이나 보고서를 깔끔하게 PDF로 내보낼 때&lt;/li&gt;
&lt;li&gt;Obsidian, Notion에서 내보낸 .md 파일을 PDF로 만들 때&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;기획자 / PM&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;회의록, 기획서를 PDF로 변환해서 공유할 때&lt;/li&gt;
&lt;li&gt;보안이 중요한 사내 문서를 외부 서비스 없이 변환할 때&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;숨은 기능들&lt;/h2&gt;
&lt;h3&gt;  Mermaid 다이어그램 → SVG 렌더링&lt;/h3&gt;
&lt;p&gt;마크다운 안에 Mermaid 코드 블록을 넣으면 자동으로 SVG 다이어그램으로 변환됩니다. 플로우차트, 시퀀스 다이어그램, 간트 차트 등을 PDF에 깔끔하게 포함할 수 있습니다.&lt;/p&gt;
&lt;h3&gt;  LaTeX 수식 지원&lt;/h3&gt;
&lt;p&gt;인라인 수식(&lt;code&gt;$E = mc^2$&lt;/code&gt;)과 블록 수식 모두 MathJax로 렌더링됩니다. 수학, 물리, 공학 문서 작성 시 매우 유용합니다.&lt;/p&gt;
&lt;h3&gt;  GitHub 저장소 통째로 가져오기&lt;/h3&gt;
&lt;p&gt;저장소 URL만 붙여넣으면 모든 마크다운 파일 목록이 트리 구조로 표시됩니다. 원하는 파일만 체크해서 일괄 PDF 변환이 가능합니다.&lt;/p&gt;
&lt;h3&gt;  폴더 업로드 시 이미지 자동 해석&lt;/h3&gt;
&lt;p&gt;로컬 폴더를 업로드하면 마크다운 안의 상대 경로 이미지(&lt;code&gt;./images/photo.png&lt;/code&gt;)가 자동으로 해석되어 PDF에 포함됩니다.&lt;/p&gt;
&lt;h2&gt;자주 묻는 질문&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Q. 정말 파일이 서버로 전송되지 않나요?&lt;/strong&gt;&lt;br&gt;네. 모든 처리는 WebAssembly 기술로 브라우저 안에서 이루어집니다. 네트워크 탭을 열어 직접 확인하실 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q. 파일 크기나 횟수 제한이 있나요?&lt;/strong&gt;&lt;br&gt;없습니다. 완전 무료이며 제한 없이 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q. 어떤 브라우저에서 작동하나요?&lt;/strong&gt;&lt;br&gt;Chrome, Edge, Safari, Firefox 등 WebAssembly를 지원하는 모든 최신 브라우저에서 작동합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q. 비공개 GitHub 저장소도 되나요?&lt;/strong&gt;&lt;br&gt;현재는 공개 저장소만 지원합니다. 비공개 저장소의 파일은 로컬에 클론한 후 폴더 업로드로 변환하세요.&lt;/p&gt;
&lt;h2&gt;마무리&lt;/h2&gt;
&lt;p&gt;마크다운을 PDF로 변환하는 데 더 이상 복잡한 설치나 파일 업로드가 필요 없습니다.&lt;/p&gt;
&lt;p&gt;  &lt;strong&gt;&lt;a href=&quot;https://dontsendfile.com/md2pdf&quot;&gt;https://dontsendfile.com/md2pdf&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;브라우저만 열면 바로 쓸 수 있습니다. 북마크해두고 필요할 때 꺼내 쓰세요.&lt;/p&gt;</description>
      <category>기타</category>
      <author>developer0hye</author>
      <guid isPermaLink="true">https://developer0hye.tistory.com/929</guid>
      <comments>https://developer0hye.tistory.com/929#entry929comment</comments>
      <pubDate>Sat, 21 Mar 2026 13:53:29 +0900</pubDate>
    </item>
  </channel>
</rss>