[{"content":"이 글은 옵시디언을 쓰면서 생긴 생각이다. 다른 노트 도구에도 비슷하게 적용될 수는 있지만, aliases, 링크되지 않은 언급, 문맥에 맞춘 링크 이름처럼 옵시디언이 제공하는 기능을 전제로 한다.\n나는 한동안 태그를 노트 정리의 기본 도구로 생각했다. Node.js에 관한 글에는 #nodejs, 쿠버네티스에 관한 글에는 #kubernetes를 붙였다. 짧고 눈에 잘 띄고, 누르면 관련 노트를 한꺼번에 볼 수 있으니 편했다.\n그런데 노트가 늘어날수록 태그가 답하지 못하는 질문도 함께 늘었다.\n이 태그는 정확히 무엇을 뜻하는가? 이 노트에는 왜 이 태그를 붙였는가? 이 태그는 다른 개념과 어떤 관계인가? 태그는 노트를 모으는 데는 능숙하지만, 그 이유를 말해 주지는 못한다. 그래서 지금은 태그를 붙이기 전에 위키링크로 표현할 수 있는지 먼저 생각한다.\n블로그의 다른 글 속성과 태그, 노트 정보를 표현하는 두 층옵시디언에서 Properties는 기계가 읽을 최소 구조를, tags는 여러 맥락을 가로지르는 주제를 표현하도록 나눈 기준을 정리했다. 2026. 09. 01#pkm ↗ 태그에는 설명을 적을 자리가 없다 #kubernetes를 누르면 쿠버네티스와 관련된 노트를 모아 볼 수 있다. 하지만 태그 자체에는 내용을 적을 수 없다. 내가 쿠버네티스를 어떻게 정의하고 있는지 설명할 자리가 없다.\n위키링크는 다르다. [[kubernetes]]라는 노트를 만들면 그 안에 현재의 정의와 판단 기준을 적을 수 있다.\n# Kubernetes 오픈소스 컨테이너 오케스트레이션 시스템이다. - [[pod|Pod]]는 하나 이상의 컨테이너를 담는, 배포 가능한 가장 작은 단위다. - [[node|Node]]는 [[pod|Pod]]가 실행되는 물리 또는 가상 워커 머신이다. 이제 Kubernetes는 목록을 여는 표지가 아니라, 계속 고칠 수 있는 하나의 노트가 된다. 다른 노트에서 [[kubernetes]]를 가리키면 링크를 따라 정의를 읽을 수 있고, 쿠버네티스 노트에서는 백링크를 통해 이 생각이 쓰인 맥락을 거꾸로 볼 수 있다.\n많아질수록 선택이 어려워진다 태그가 열 개일 때는 별문제가 없다. 백 개가 되면 새 노트를 쓸 때마다 이미 있는 태그를 기억해야 한다. #infrastructure와 #kubernetes, #observable과 #observability 그리고 #monitoring 중 무엇을 썼는지 확인하는 일이 생긴다. 다시 찾을 때도 비슷한 태그를 하나씩 열어 봐야 한다.\n물론 이것은 태그만의 잘못은 아니다. 모든 단어를 위키링크로 만들면 똑같은 문제가 링크에서 반복된다. 내용 없는 노트 백 개를 만들어 놓고 태그 백 개를 없앴다고 해도 시스템은 단순해지지 않는다.\n차이는 링크 대상에 내용을 쌓을 수 있다는 데 있다. 반복해서 설명하거나 다른 이름으로 자주 부르거나, 여러 생각의 기준점이 될 개념만 노트로 만든다. 그렇게 할 가치가 없는 말이라면 링크도 태그도 만들지 않는다.\n계층보다 관계가 필요하다 옵시디언은 #infrastructure/kubernetes처럼 계층 태그를 지원한다. 그래서 태그끼리 전혀 연결할 수 없다고 말하면 정확하지 않다. 다만 중첩 태그가 표현하는 것은 주로 상위·하위의 분류 관계다.\n내가 노트에서 남기고 싶은 관계는 그보다 다양하다.\n[[kubernetes|쿠버네티스]]를 사용할 때 [[infra|인프라]]를 어떻게 가져갈지 먼저 고민해야 한다. [[pod|Pod]]는 [[node|Node]]에서 실행되는 더 작은 단위이므로 리소스 분배를 고려해야 한다. 첫 문장은 조건과 우선순위를, 둘째 문장은 두 개념을 나누는 기준을 말한다. #infrastructure/kubernetes 같은 계층으로는 이 관계를 자연스럽게 남기기 어렵다. 위키링크가 관계를 자동으로 만들어 주는 것은 아니지만, 적어도 문장이 관계를 설명할 자리를 준다.\n같은 대상을 다른 이름으로 부를 수 있다 같은 개념도 맥락이나 언어에 따라 이름이 달라진다. kubernetes, k8s, 쿠버네티스를 각각 태그로 만들면 하나의 대상을 세 갈래로 나누게 된다.\n옵시디언에서는 정본 노트 하나에 aliases를 적을 수 있다.\n--- aliases: - k8s - 쿠버네티스 - 쿠버 --- 이후 쿠버라는 별칭으로 링크하고 싶다면 옵시디언은 [[kubernetes|쿠버]]처럼 같은 노트를 가리키는 링크를 만든다. Backlinks의 링크되지 않은 언급에서도 파일 이름과 별칭이 쓰인 곳을 찾아볼 수 있다. 이미 본문에 kubernetes라고 적어 둔 노트를 발견한 뒤, 필요한 것만 실제 링크로 바꾸는 식으로 쓸 수 있다. 링크를 잊었더라도 관계를 발견할 수 있다는 뜻이다.\n한 문장에서만 표현을 바꾸고 싶다면 별칭을 추가할 필요도 없다.\n요즘은 [[kubernetes|오픈소스로 컨테이너를 오케스트레이션하는 방법]]을 다시 생각하고 있다. 링크 대상은 kubernetes로 유지하면서도 문장은 원래 흐름대로 읽힌다. 노트 제목에 문장을 억지로 맞추지 않아도 된다.\n그래도 태그가 더 나은 때가 있다 여기까지 쓰면 태그를 전부 없애도 될 것 같다. 하지만 실제로는 그렇지 않았다.\n태그는 같은 주제의 노트를 즉시 모으고 필터링하는 데 여전히 단순하다. 예를 들어 개발, 투자, 일상 기록에 모두 걸쳐 있는 security 노트를 한 번에 찾고 싶다면 태그 하나가 편하다. 그 결과를 얻기 위해 내용이 거의 없는 [[Security]] 노트를 만들고 모든 글에 링크하는 것은 오히려 돌아가는 방법일 수 있다.\n그래서 현재 기준은 이렇다.\n그 자체로 설명할 내용이 있는 개념이나 대상이면 위키링크를 쓴다. 특히 고유명사는 위키링크를 우선한다. 두 생각의 관계를 문장으로 말할 수 있으면 위키링크를 쓴다. 여러 맥락을 가로질러 같은 주제로 반복해서 필터할 때만 태그를 쓴다. 다시 찾을 구체적인 이유가 없다면 둘 다 쓰지 않는다. 결국 내게 위키링크는 태그의 완전한 대체재라기보다 먼저 검토할 기본값에 가깝다. 태그가 목록을 만든다면 위키링크는 설명할 장소와 관계를 만든다. 노트를 다시 읽을 때 필요한 것은 비슷한 글의 목록만이 아니라, 왜 이어 놓았는지 이해할 수 있는 문맥이기 때문이다.\n","permalink":"https://blog.yoonho.site/use-wikilinks-instead-tags/","summary":"\u003cp\u003e이 글은 옵시디언을 쓰면서 생긴 생각이다. 다른 노트 도구에도 비슷하게 적용될 수는 있지만, \u003ccode\u003ealiases\u003c/code\u003e, 링크되지 않은 언급, 문맥에 맞춘 링크 이름처럼 옵시디언이 제공하는 기능을 전제로 한다.\u003c/p\u003e","title":"태그보다 위키링크를 먼저 쓰는 이유"},{"content":"노트 정리법을 꽤 오래 찾아다녔다. Zettelkasten, PARA, Bullet Journal, ACE까지 하나씩 써봤다. 각각 분명히 좋은 방법이었다. 그런데 그대로 가져오면 내 생활과 어긋나는 부분이 생겼다.\n나는 노트를 쓰는 시간보다 시스템을 고치는 시간이 더 길어지는 순간을 여러 번 겪었다. 폴더를 다시 나누고, 태그를 합치고, 속성을 추가했다가 지웠다. 구조는 점점 정교해졌는데 새 노트를 어디에 둘지는 여전히 어려웠다.\n결국 다른 사람의 방법을 하나 더 찾는 대신, 내가 실제로 반복하는 판단을 규칙으로 만들기로 했다. 이름은 You-Know Management, 줄여서 YKM이라고 붙였다. Yoonho를 you know로 읽은 말장난이기도 하다.\nYKM은 내가 아는 것을 많이 쌓는 방법이 아니다. 무엇을 어떻게 알게 되었고, 그때의 기록과 지금의 해석을 어떻게 서로 덮어쓰지 않을지를 관리하는 방법이다.\n블로그의 다른 글 내 라이프사이클에 맞는 노트 시스템을 찾는 과정여러 노트테이킹 방법을 써 보며 겪은 실패와, 옵시디언에서 계속 쓰기 위해 세운 기준을 정리했다. 2026. 08. 20#pkm ↗ 모든 것을 한곳에 넣지 않는 이유 노트에서 보존하고 싶은 것은 정보의 양보다 변화의 경계다.\n그때 실제로 무슨 일이 있었는가? 그때 외부에서 무엇을 만났는가? 지금 나는 그것을 어떻게 이해하고 있는가? 다른 생각과 어떤 의미로 이어지는가? 이 네 질문을 한 파일에 모두 넣으면 곧 경계가 흐려진다. 외부 자료를 요약한 문장과 내 해석이 섞이고, 과거의 판단을 지금의 결론에 맞게 고쳐 쓰게 된다. 나중에는 무엇이 원문이었고 무엇이 내 생각이었는지 다시 분리해야 한다.\n그래서 YKM은 기억의 역할을 나눈다.\n수단 보존하는 것 기본 동작 sources/ 외부 세계를 특정 시점에 만난 캡처 원문과 출처를 보존한다 log/ 특정 시점에 일어난 일과 당시의 판단 과거를 덮어쓰지 않고 쌓는다 notes/ 현재의 이해·해석·원칙 새 근거와 반례에 따라 계속 고친다 wikilink 노트와 대상 사이의 의미 관계 복사하지 않고 문장 안에서 참조한다 atlas/ 여러 노트를 읽는 순서와 질문 사람이 만든 경로로 탐색한다 분리한다고 연결이 끊어지는 것은 아니다. 오히려 각 파일이 무엇을 책임지는지 분명해지면 링크를 따라갈 때 변화가 더 잘 보인다.\n시간축은 언제 다시 고칠지를 본다 노트의 시간은 생성일과 수정일만으로 설명되지 않는다. 내가 중요하게 보는 것은 이 노트에 관심이 언제 다시 돌아오고, 그 갱신이 언제 끝나는가다.\n이를 점·선분·반직선으로 생각한다.\n형태 관심과 갱신 예시 점({t₀}) 한 번의 관심 구간에서 작성과 마감이 함께 끝난다 회의록, 당시의 결정, 외부 자료 캡처 선분([t₀,t₁]) 여러 번 다시 열지만 종료 조건이 있다 진행 중인 프로젝트 지도, 판단 중인 조사 초안 반직선([t₀,∞)) 끝을 정하지 않고 새 근거가 생길 때마다 고친다 원칙, 개념, 계속 탐색할 관심사 지도 네 시간 동안 쓴 회의록도 회의가 끝난 뒤 다시 고치지 않는다면 점이다. 반대로 짧은 글이라도 여러 날 동안 다시 열어 고치다가 마감한다면 선분이다. 중요한 것은 작성 시간이 아니라 관심이 독립적으로 돌아오는 횟수와 끝의 유무다.\nBullet Journal은 시간 순서로 현재를 운영하고, PARA는 시간이 지나며 프로젝트를 Archive로 옮긴다. ACE는 Atlas와 Calendar를 나눠 지식과 시간을 바라본다. YKM도 시간이 노트의 다음 행동을 바꾼다고 생각하지만, 작성 순서나 보관 위치보다 언제 같은 정본을 다시 고치고 언제 닫을지에 초점을 맞춘다.\n시간축을 더 자세히 정리한 내용은 노트는 언제 끝날까에 따로 적었다.\n공간축은 이 파일을 어떻게 취급할지 정한다 하나의 파일은 한 곳에만 둘 수 있다. 하지만 하나의 노트는 여러 주제와 관련될 수 있다. security이면서 privacy이고 architecture인 노트도 있다.\n주제로 폴더를 나누면 셋 중 하나를 골라야 한다. 복사본을 만들면 어느 파일이 정본인지 다시 관리해야 한다. 그래서 YKM에서 폴더는 주제를 설명하지 않는다. 이 파일을 앞으로 어떻게 취급할지만 정한다.\n위치 취급 방식 inbox/ 아직 판단하지 않은 캡처. 30일 안에 검토한다 sources/ 남이 만든 원문과 출처. 본문을 고치지 않는다 log/ 그때의 사건과 판단. 현재의 결론으로 덮어쓰지 않는다 notes/ 내가 쓰고 앞으로도 고칠 해석·원칙·개념 atlas/ 노트를 보관하는 곳이 아니라 읽는 경로를 만드는 곳 새 노트를 처음 만들 때는 종류를 맞히지 않고 세 질문을 묻는다.\n아직 판단이 끝나지 않았는가? 그렇다면 inbox/에 둔다. 외부에서 들어온 자료인가? 그렇다면 sources/에 보존한다. 내가 만든 내용이라면 나중에 계속 고칠 것인가? 그렇다면 notes/, 아니라면 log/에 둔다. log/에는 별도의 맥락·프로젝트 하위 폴더를 만들지 않는다. 새 기록은 log/ 바로 아래에 두고, 맥락은 파일명과 본문, wikilink와 MOC로 표현한다.\n그리고 노트의 이주는 없다. 성질이 달라졌다면 기존 파일이 변신한 것이 아니라 다른 역할의 노트가 새로 생긴 것이다.\n외부 원문은 sources/에 남기고, 그에 대한 내 해석은 notes/에 새로 쓴다. 당시 프로젝트 기록은 log/에 남기고, 반복해서 쓸 원칙은 notes/에 새로 추출한다. 검토 전 AI 초안은 inbox/에 두고, 사람이 채택한 내용은 맞는 자리에 새 정본으로 만든다. 두 노트는 wikilink로 연결한다. 이전 캡처가 독립적으로 남을 가치가 없다면 참조를 확인한 뒤 삭제한다. 파일 이동에 의미를 맡기지 않고 각 노트의 역할을 처음부터 끝까지 유지하는 방식이다.\n공간축을 만든 과정을 더 자세히 보고 싶다면 노트는 어디에 있어야 할까에서 이어서 볼 수 있다.\n폴더가 내려놓은 질문을 나눠 맡긴다 폴더를 단순하게 만드는 것만으로는 충분하지 않았다. 폴더가 내려놓은 질문을 Properties, tags, wikilink, MOC에 정확히 나눠줘야 했다.\n수단 답하는 질문 폴더 이 노트를 어떻게 취급할 것인가? Properties 기계가 어떤 값으로 정렬·필터할 것인가? tags 어떤 횡단 주제로 다시 찾을 것인가? wikilink 무엇과 어떤 의미로 이어지는가? Atlas MOC 어떤 순서와 관점으로 읽을 것인가? Properties는 최소한만 둔다 기본 Properties는 created, tags, sources, aliases 네 개다. created와 tags는 항상 두고, sources와 aliases는 값이 있을 때만 쓴다. 더는 고치지 않지만 탐색·회고 경로로 남길 MOC에만 state: archived를 허용한다.\ntype, status, confidence, updated 같은 값은 만들지 않는다. 폴더나 파일명, 본문에서 이미 알 수 있거나 실제로 필터하지 않는 값이라면 한 번 더 저장할 이유가 없다. 확신이 낮은 내용은 confidence: low로 감추기보다 본문의 열린 질문에 적는다.\ntags는 횡단 주제만 남긴다 태그는 한 노트에 최대 세 개만 쓴다. 소문자 영문 kebab-case를 사용하고 계층 태그는 만들지 않는다. 새 태그를 붙이기 전에는 세 가지를 확인한다.\n이 태그로 다시 찾을 노트가 세 개 이상인가? 종류·상태·위치·프로젝트명이 아니라 실제 주제인가? 이 노트가 그 태그에 관한가? 단지 관련만 있는 것은 아닌가? 사람·조직·제품·기술·사건 같은 고유명사는 태그가 아니라 wikilink로 연결한다. 태그는 같은 주제로 결과를 모으는 데는 좋지만, 왜 연결했는지는 말해 주지 못하기 때문이다.\nwikilink는 관계를 문장으로 말한다 링크는 많다고 좋은 것이 아니다. 본문 문장 안에서 두 대상의 관계를 설명할 수 있을 때만 만든다.\n세션을 서버에 두지 않으면 [[statelessness-in-system-design|수평 확장]]이 쉬워진다. 이 문장은 두 노트가 같은 주제라는 사실보다 무상태성이 수평 확장과 어떤 관계인지 보여 준다. 링크 대상의 제목에 맞춰 문장을 비틀지 않고, 현재 문맥에서 그 대상이 맡는 역할을 드러낸다.\nMOC는 색인이 아니라 지도다 태그와 검색은 무엇이 있는지 보여 주지만 무엇부터 읽을지는 알려 주지 않는다. 한 주제를 찾으며 여러 노트를 헤매기 시작했거나, 하나의 태그가 30개를 넘었거나, 프로젝트의 기록과 재사용할 지식을 한 흐름으로 회고하고 싶을 때 atlas/에 MOC를 만든다.\nMOC는 읽기 시작점과 현재 위치, 관점이 갈리는 지점을 보여 주는 지도다. 링크마다 그 경로에서 왜 읽는지 한 줄을 쓴다. 같은 노트가 여러 MOC에 나타나도 괜찮다. 파일은 하나지만 읽는 목적은 여러 개일 수 있기 때문이다.\nProperties·tags·wikilink의 차이는 속성과 태그, 노트 정보를 표현하는 두 층에서, 링크와 MOC의 관계는 위키링크와 MOC, 관계와 읽기 경로 잇기에서 더 자세히 다뤘다.\n실제로는 이렇게 운영한다 YKM의 흐름을 한 번에 쓰면 아래와 같다.\n캡처 → inbox/ ↓ 사람이 판단한다. 파일은 옮기지 않는다. 외부 자료 → sources/에 새 캡처 당시의 사건·활동 → log/에 새 기록 계속 발전시킬 해석 → notes/에 새 글 ↖ 원래 캡처·source·log와 필요한 관계를 연결 프로젝트에서 재사용 가치가 생기면 → notes/에 원칙 1~3개를 새로 추출 탐색 비용이 커지면 → atlas/에 MOC 작성 주 1회 15분 정도 inbox/를 비운다. 한 달이 넘은 캡처는 정말 지킬 가치가 있는지 다시 보고, 끝난 프로젝트에서는 다시 쓸 원칙 한두 개만 추출한다. 분기마다 한 번만 저빈도 태그와 동의어, MOC가 필요한 큰 태그를 살핀다.\n자동으로 모든 것을 롤오버하지 않는다. 다시 읽고 남길 것을 고르는 약간의 마찰이 필터가 되기 때문이다. 시스템의 목적은 모든 것을 보존하는 것이 아니라, 다음에 다시 쓸 수 있는 것과 당시의 기록으로 남길 것을 구분하는 데 있다.\n원문·당시 기록·현재 해석을 나누는 구체적인 예시는 원문은 보존하고, 기록은 쌓고, 생각은 연결한다에 적었다.\n결국 정리법보다 책임의 경계였다 예전에는 미래의 모든 노트를 설명할 수 있는 폴더 구조를 만들고 싶었다. 지금은 그런 구조가 가능하다고 생각하지 않는다. 주제는 계속 늘고, 관심은 바뀌고, 같은 자료를 다시 읽은 나는 이전과 다른 결론을 내릴 수 있다.\n대신 각 수단의 책임을 작게 만든다. 폴더는 취급 방식, Properties는 최소 구조, tags는 횡단 주제, wikilink는 의미 관계, MOC는 읽는 순서를 맡는다. sources/는 남의 말을 지키고, log/는 그때의 나를 남기고, notes/는 지금의 내가 계속 고친다.\nYKM이 다른 사람에게도 정답일 것이라고 생각하지는 않는다. 다만 적어도 나는 새 노트를 만들 때 예전만큼 오래 망설이지 않는다. 시스템을 고치는 시간보다 노트를 쓰고 다시 읽는 시간이 조금 더 많아졌다. 지금은 그 정도면 충분하다.\nAI가 이 볼트를 다룰 때 쓰는 RULES.md 아래 블록은 AI 에이전트에게 그대로 제공할 수 있도록 YKM의 운영 규칙만 명령형으로 정리한 것이다. 도구에 맞춰 볼트 경로와 검사 명령만 조정하면 된다.\n# RULES.md — You-Know Management (YKM) 이 볼트는 원문, 당시 기록, 현재 해석을 서로 덮어쓰지 않고 연결하기 위한 지식 시스템이다. 파일을 수정하거나 만들기 전에 아래 규칙을 따른다. ## 1. 각 수단의 책임 - 폴더는 노트의 취급 방식을 표현한다. - Properties는 기계가 읽을 최소 구조만 담는다. - tags는 여러 맥락을 가로지르는 주제만 표현한다. - wikilink는 대상과 생각 사이의 의미 관계를 문장 안에 표현한다. - Atlas MOC는 읽기 시작점, 현재 위치, 관점이 갈리는 지점을 안내한다. - 같은 정보를 둘 이상의 수단에 중복해서 기록하지 않는다. ## 2. 새 노트의 위치 새 노트를 만들기 전에 다음 질문을 순서대로 묻는다. 1. 아직 사람이 판단하지 않은 캡처인가? 그러면 `inbox/`에 만든다. 2. 외부에서 들어온 원문인가? 그러면 `sources/`에 만들고 본문을 임의로 고치지 않는다. 3. 사람이 작성한 내용이라면 앞으로 계속 고칠 글인가? - 예: `notes/`에 만든다. - 아니오: `log/`에 당시 기록으로 만든다. - `atlas/`에는 MOC와 진입점만 만든다. - `_attachments/`에는 이미지와 첨부 파일만 둔다. - `_system/`에는 규칙, 템플릿, 검사 도구만 둔다. - 새로운 최상위 폴더를 만들지 않는다. - 새 `log/` 기록은 `log/` 바로 아래에 만든다. 맥락·프로젝트 하위 폴더를 만들지 않는다. - 일반적인 `archive/` 폴더를 만들지 않는다. ## 3. 노트의 이주는 없다 - 노트의 성질이 달라지면 기존 파일을 옮기거나 덮어쓰지 않는다. - 달라진 역할에 맞는 새 노트를 알맞은 위치에 만들고 이전 노트와 연결한다. - 외부 원문은 `sources/`에 남기고 해석은 `notes/`에 새로 쓴다. - 당시 사건은 `log/`에 남기고 재사용할 원칙은 `notes/`에 새로 추출한다. - 이전 캡처를 삭제하기 전에 참조와 독립적인 보존 가치를 확인한다. - 파일을 삭제하기 전에 해당 파일을 참조하는 wikilink를 먼저 고친다. ## 4. 시간에 따른 수정 - `sources/`와 `log/`는 한 관심 구간이 닫히면 현재 관점에 맞춰 다시 쓰지 않는다. - 같은 사건이 다시 일어나거나 외부 자료가 바뀌면 새 노트를 만든다. - `notes/`는 새 근거, 반례, 경험이 생길 때 같은 정본을 계속 갱신한다. - 종료 조건이 있는 프로젝트 MOC는 종료 뒤 탐색·회고 가치가 있을 때만 `state: archived`로 동결한다. - 탐색 가치가 없는 노트는 참조를 정리한 뒤 삭제한다. ## 5. Front matter 모든 지식 노트는 YAML front matter를 사용한다. ```yaml --- created: YYYY-MM-DD tags: [] sources: - \u0026#34;https://example.com/\u0026#34; aliases: - 다른 이름 --- ``` - `created`와 `tags`는 필수다. - `tags`는 항상 배열이며 0~3개다. - `sources`와 `aliases`는 값이 있을 때만 쓴다. 빈 배열을 남기지 않는다. - `state: archived`는 더는 고치지 않지만 탐색·회고 경로로 남길 `atlas/` MOC에만 쓴다. - `type`, `kind`, `status`, `reviewed`, `confidence`, `updated`, `title`, `author` 등 새 프로퍼티를 만들지 않는다. - 확인하지 못한 사실과 낮은 확신은 프로퍼티가 아니라 본문의 `열린 질문` 절에 쓴다. - 다음 행동은 상태 프로퍼티가 아니라 본문에 쓴다. ## 6. Tags - 태그는 이 노트가 실제로 다루는 횡단 주제에만 붙인다. - 한 노트에 최대 3개만 사용한다. - 소문자 영문 kebab-case를 사용한다. - 계층 태그와 본문의 `#해시태그`를 사용하지 않는다. - 새 태그는 같은 이유로 다시 찾을 노트가 3개 이상일 때만 만든다. - 폴더 위치, 노트 종류, 상태, 난이도, 프로젝트명을 태그로 만들지 않는다. - 사람, 조직, 제품, 기술, 사건 같은 고유명사는 태그 대신 wikilink로 연결한다. - 하나의 태그가 30개를 넘으면 세분화보다 Atlas MOC가 필요한지 먼저 검토한다. ## 7. Wikilinks - 의미 있는 관계가 있을 때만 링크한다. 최소 링크 수는 없다. - 링크는 가능하면 본문 문장 안에 두고 관계를 자연어로 설명한다. - 링크 대상의 제목에 맞추려고 현재 문장을 비틀지 않는다. 필요하면 `[[대상|현재 문맥의 표현]]`을 쓴다. - 모든 명사를 링크하지 않는다. 반복해서 생각하거나 근거·대조·전제로 사용하는 대상만 연결한다. - `sources/` 원문은 링크가 없어도 정상이다. 그 원문을 사용한 `notes/`가 관계를 만든다. - AI가 관련 링크를 제안할 때는 최대 3개까지만 제안하고 억지 연결을 만들지 않는다. ## 8. Atlas MOC - `atlas/index.md`를 단일 진입점으로 사용한다. - 한 주제를 찾으며 여러 노트를 헤매거나 태그가 30개를 넘을 때 MOC 생성을 검토한다. - MOC는 자동 생성 목록이 아니라 사람이 읽을 경로를 설계한 지도다. - 모든 링크 옆에 그 경로에서 왜 읽는지 한 줄을 쓴다. - 같은 노트는 읽는 목적이 다르면 여러 MOC에 연결할 수 있다. 원본 파일은 복제하지 않는다. - MOC끼리 상위·동료 지도로 연결할 수 있다. - 읽기 시작점, 관점이 갈리는 지점, 아직 없는 반례·사례를 드러낸다. ## 9. AI 협업 - AI는 원문을 임의로 바꾸지 않는다. - AI가 만든 요약·초안은 기본적으로 `inbox/`에 두고 사람이 검토하게 한다. - 사용자가 특정 정본의 생성·수정을 명시적으로 요청한 경우에만 해당 파일을 직접 편집한다. - 사실, 인용, 해석을 구분한다. - 확인할 수 없는 내용은 확정하지 않고 `열린 질문`으로 남긴다. - 사실의 확정, 핵심 주장 선택, 프로젝트 의사결정은 사용자에게 남긴다. - 기존 파일과 사용자 작성 내용을 먼저 확인하고, 관련 없는 내용을 삭제하거나 덮어쓰지 않는다. ## 10. 저장 전 확인 - 새 노트가 처음부터 맞는 폴더에 만들어졌는가? - 새 `log/` 기록이 `log/` 바로 아래에 있는가? - 파일명이 볼트 전역에서 유일한가? - `created`와 배열 형태의 `tags`가 있는가? - 태그가 3개 이하이며 실제 주제인가? - 고유명사·종류·상태·위치를 태그로 만들지 않았는가? - 근거가 있는 노트에 `sources`가 있는가? - 사실·인용·해석과 열린 질문이 구분되어 있는가? - 기존 노트를 옮기거나 현재 관점으로 과거 기록을 덮어쓰지 않았는가? - 삭제 전 참조를 먼저 정리했는가? 가능하다면 저장 후 볼트 검사기를 실행하고, 기존 위반과 이번 변경으로 생긴 위반을 구분해 보고한다. ","permalink":"https://blog.yoonho.site/my-note-taking-system-ykm/","summary":"\u003cp\u003e노트 정리법을 꽤 오래 찾아다녔다. Zettelkasten, PARA, Bullet Journal, ACE까지 하나씩 써봤다. 각각 분명히 좋은 방법이었다. 그런데 그대로 가져오면 내 생활과 어긋나는 부분이 생겼다.\u003c/p\u003e","title":"나의 노트 정리법(YKM)"},{"content":"노트를 정리하면서 주로 고민한 것은 어디에 둘 것인가였다. 그런데 폴더를 어느 정도 정리하고 나니 다른 질문이 남았다.\n“이 노트는 언제까지 고쳐야 하지?”\n모든 노트를 계속 다듬으면 그때의 기록이 사라진다. 반대로 한 번 쓴 노트를 전부 그대로 두면 새로 알게 된 사실과 생각이 여기저기 흩어진다. 생성일과 수정일은 남아 있지만 날짜만으로는 다음 행동을 정하기 어려웠다.\n그래서 노트를 시간축 위에 놓아 보기로 했다. 중요한 것은 언제 만들었는지가 아니라 관심이 언제 다시 돌아오고, 언제 닫히는가였다.\nBullet Journal: 시간축을 기준으로 노트가 배치된다. 다른 노트를 보려면 시간축을 거슬러 올라가야 하고 인덱스 페이지에 의존해야 한다. PARA Method: 만료된 프로젝트와 무관심해진 영역들을 archive 폴더로 이동 시킨다. 즉 시간의 변화에 따라 공간이 뒤틀린다. ACE Framework: 시간과 공간이 분리되어 있다. 내 설계와도 비슷하다고 느꼈다. 다만 나는 Atlas 쪽을 atlas/·notes/·sources/로, Calendar 쪽을 log/로 나눠 쓴다. 세 방법의 공통점은 삶의 영역에서 행동의 변화까지 이끌어낸다. 그런 부분에서 긍정적인 효과가 있으나 현재 내가 다루고자 하는 내용과는 핀트가 조금 다르다.\n생성일 하나로는 노트의 시간을 설명할 수 없다 파일에는 생성일이 있다. 옵시디언에서도 날짜를 속성으로 남길 수 있고, 파일 시스템에는 마지막 수정 시각이 기록된다. 처음에는 이 정도면 노트의 시간을 충분히 설명한다고 생각했다.\n그런데 같은 날 만든 노트라도 살아가는 방식은 다르다.\n회의록은 회의가 끝나면 그날의 기록으로 남는다. 인박스에 적어둔 메모는 며칠 동안 검토하다가 다른 노트가 되거나 사라진다. 내가 계속 사용하는 원칙이나 개념 노트는 몇 년 뒤에도 새로운 근거가 생기면 다시 고친다.\n셋은 생성일이 같아도 다시 관심을 기울이는 방식이 다르다. 결국 노트의 시간은 날짜 하나보다 독립적인 관심과 갱신이 이어지는 구간에 가깝다.\n블로그의 다른 글 내 라이프사이클에 맞는 노트 시스템을 찾는 과정여러 노트테이킹 방법을 써 보며 겪은 실패와, 옵시디언에서 계속 쓰기 위해 세운 기준을 정리했다. 2026. 08. 20#pkm ↗ 시간 형태를 정한 뒤 실제 파일을 어느 공간에 둘지는 공간축 글에서 이어서 다룬다.\n점, 선분, 반직선 점·선분·반직선은 시간을 정확히 재는 수학 모델이 아니다. 노트를 어느 폴더에 둘지 강제하는 분류표도 아니다. 한 노트에 관심이 돌아오는 모양을 비교하기 위한 운영 비유다.\n점({t₀})은 한 번의 관심 구간 안에서 작성과 마감이 함께 일어나고, 이후 독립적인 갱신 회차가 없는 노트다. 회의록, 당시의 판단을 남긴 로그, 나중에 참조하기 위해 보관한 외부 원문이 여기에 가깝다.\n점이라고 해서 작성 시간이 0이라는 뜻은 아니다. 네 시간짜리 회의 중 회의록을 계속 고쳤더라도, 회의와 직후 정리라는 한 번의 관심 구간이 닫힌 뒤 다시 갱신하지 않는다면 점이다. 반대로 짧은 문서라도 며칠 뒤 다시 열어 고치고 마감한다면 선분에 가깝다.\n선분([t₀, t₁])은 서로 다른 시점에 다시 관심을 기울여 갱신하지만 종료 조건이 있는 노트다. 판단을 기다리는 조사 초안과 종료 시점이 있는 프로젝트 MOC가 여기에 가깝다.\n선분에서 중요한 것은 오른쪽 끝이다. 인박스 캡처는 기한 안에 검토하고 새 정본을 만들거나 삭제한다. 프로젝트 MOC는 프로젝트가 끝났다는 이유만으로 자동으로 state: archived가 되지 않는다. 더는 고치지 않지만 관심 영역의 탐색·회고 경로로 계속 유용할 때만 동결 상태로 남긴다. 탐색 가치도 없다면 참조를 정리한 뒤 삭제한다.\n반직선([t₀, ∞))은 시작은 있지만 미리 정한 끝이 없는 노트다. 내가 계속 사용하는 원칙, 개념, 관심사 MOC가 여기에 가깝다. 내 볼트에서는 주로 notes/가 이 역할을 맡는다.\n반직선이라고 매일 고친다는 뜻은 아니다. 몇 달 동안 손대지 않을 수도 있다. 다만 새로운 통찰이나 반례, 변경된 사실을 만났을 때 같은 노트를 다시 열어 고칠 수 있다. 관심이 돌아올 가능성을 미리 닫지 않은 것이다.\n시간축은 폴더 분류표가 아니다 같은 주제의 노트도 서로 다른 시간 형태를 가질 수 있다.\n예를 들어 한 프로젝트의 보안 회의록은 점이다. 프로젝트가 진행되는 동안 사용하는 보안 체크리스트는 선분일 수 있다. 여러 프로젝트에서 계속 다듬어 쓸 보안 원칙은 반직선에 가깝다.\n그래서 회의록, 보안, 개념 같은 노트 종류를 하나 더 저장한다고 문제가 해결되지는 않았다. 종류는 무엇에 관한 노트인지 설명하지만, 언제 관심을 닫고 다시 열지는 알려주지 않는다.\n나는 별도의 lifecycle 속성을 모든 노트에 붙이지 않기로 했다. 폴더 구조가 시간 형태를 암시할 수는 있지만, 점·선분·반직선을 폴더나 속성에 강제로 저장하지 않는다. created는 만든 날이고 file.mtime은 마지막 수정 시각일 뿐이라 과거의 관심 회차 전체를 보여 주지도 못한다. 이 구분은 정밀한 편집 로그가 아니라 앞으로 그 노트를 어떻게 다시 다룰지 생각하기 위한 모델이다.\n오른쪽 끝을 정하지 않으면 생기는 일 시간 형태를 나눈 뒤 가장 크게 달라진 곳은 인박스와 로그였다.\n예전에는 인박스의 메모도 언젠가 쓸 수 있다는 이유로 오래 남겨두곤 했다. 하지만 선분에는 끝이 있어야 한다. 검토해서 내 생각으로 발전시킬 수 있으면 notes/에 새 노트를 만들고, 외부 자료라면 sources/에 새 캡처를 만든다. 원래 인박스 캡처는 독립 가치가 있으면 연결해 남기고, 아니라면 지운다.\n로그는 반대다. 지금의 생각에 맞게 계속 다듬고 싶어도 멈춰야 할 때가 있다. 지난 결정의 근거를 현재 기준으로 고쳐 버리면 왜 그런 선택을 했는지 돌아볼 수 없다. 잘못 판단했던 기록도 그때의 상태로 남아 있어야 의미가 있다. 원문은 sources/에, 사건의 맥락은 log/에 남기고, 그 기록에서 재사용할 해석만 별도의 notes/에서 계속 고친다.\n반직선인 노트에는 다른 책임이 생긴다. 살아 있는 노트라고 해놓고 새 근거를 만날 때마다 새 파일만 만들면 정본이 여러 개가 된다. 계속 참조할 원칙이라면 기존 노트로 돌아가 문장을 고치고, 반례를 붙이고, 더 이상 맞지 않는 내용을 걷어내야 한다.\n결국 점은 보존하고, 선분은 끝을 처리하고, 반직선은 다시 쓴다.\n노트의 시간은 멈춤을 설계하는 일이다 노트의 시간 축이라고 하면 보통 생성일, 수정일, 일간 노트를 먼저 떠올린다. 나도 그랬다. 그런데 실제로 정리를 어렵게 만든 것은 날짜가 부족해서가 아니라 멈춤의 기준이 없어서였다.\n이 노트는 그때의 기록으로 남아야 하는가. 정해진 시점에 처리되어야 하는가. 새 근거가 생길 때마다 계속 고쳐야 하는가.\n이 세 질문에 답하면 모든 노트에 복잡한 상태를 붙이지 않아도 다음 행동이 보인다. 과거를 보존할 노트와 앞으로 자랄 노트를 같은 방식으로 다루지 않게 된다.\n아마 이 구분도 실제 사용 속에서 조금씩 바뀔 것이다. 다만 지금의 나는 노트를 언제 만들었는지보다, 관심이 언제 돌아오고 언제 닫히는지를 먼저 생각한다. 동결한 MOC를 언제 남기고 지울지는 위키링크와 MOC 글에서, 원문·기록·계속 고칠 생각을 나누는 실제 규칙은 sources, log, wikilink 글에서 이어서 정리했다. 시간축은 날짜를 정리하는 방법보다 노트의 끝을 생각하는 방법에 가깝다.\n","permalink":"https://blog.yoonho.site/note-time-axis/","summary":"\u003cp\u003e노트를 정리하면서 주로 고민한 것은 어디에 둘 것인가였다. 그런데 폴더를 어느 정도 정리하고 나니 다른 질문이 남았다.\u003c/p\u003e","title":"노트는 언제까지 고쳐야 할까"},{"content":"옵시디언에 메모를 쌓다 보면 비슷해 보이는 세 가지를 한곳에 넣고 싶어진다. 읽은 글의 내용, 당시 있었던 일, 그리고 그 둘을 연결한 내 생각이다. 나도 예전에는 이것을 한 노트에 담고 태그를 많이 붙이면 나중에 찾을 수 있다고 생각했다.\n그런데 시간이 지나면 무엇이 원문이고, 무엇이 그때의 판단이며, 지금도 고쳐야 하는 내 생각인지 구분하기 어려워진다. 그래서 지금은 기록의 역할을 나눈다.\nsources/는 남의 말을 보존한다. log/는 그때의 상태를 쌓는다. notes/는 내 생각을 계속 고친다. wikilink는 파일을 옮기지 않고 관계를 문장 안에 남긴다. 핵심은 많이 분류하는 것이 아니다. 한 사실을 두 곳에 저장하지 않는 것이다.\n파일이 놓이는 곳은 하나지만, 의미 있는 관계는 링크로 계속 이어진다.\n원문은 sources/에 보존한다 sources/는 내가 쓴 글이 아닌 것을 보관하는 곳이다. 외부 글, 영상, 문서에서 알게 된 내용을 나중에 참고할 수 있도록 남긴다. 이때 중요한 것은 요약을 잘하는 것보다 무엇이 원문에서 온 말인지 보존하는 것이다.\n그래서 sources/에 있는 노트의 본문은 고치지 않는다. 참고한 URL이나 출처 한 줄을 남기고, 원문에서 읽은 내용을 보관한다. 지금의 내가 그 내용을 다르게 해석하게 되었다고 해서 과거의 원문 노트를 다시 써 버리면, 출처와 해석의 경계가 흐려진다.\nsources라는 이름은 폴더와 Properties에 모두 등장한다. 하지만 역할은 조금 다르다. sources/는 남의 원문을 보존하는 자리이고, sources property는 현재 노트를 뒷받침하는 URL이나 출처 노트를 가리키는 근거 목록이다. 이름이 같다고 하나의 정보를 두 번 적는 것은 아니다.\n외부 글을 읽다가 내 생각이 생겼다면 원문 노트에 덧붙이지 않는다. 내가 이해한 내용이나 다른 맥락에 적용한 판단은 별도의 notes/ 노트로 만든다. 그러면 나중에 원문으로 돌아갔을 때 “저자가 말한 것”과 “내가 거기서 가져온 것”을 다시 구분할 수 있다.\nlog/에는 당시의 상태를 쌓는다 log/는 그때의 사건과 판단을 남기는 곳이다. 회의에서 어떤 이야기가 오갔는지, 프로젝트가 그 시점에 어디까지 왔는지, 투자나 생활에서 어떤 판단을 했는지를 log/ 아래에 기록한다.\n로그는 현재의 내가 과거를 다시 평가해 고쳐 쓰는 문서가 아니다. 그때 무엇을 알고 있었고 어떤 선택을 했는지 보존하는 기록이다. 지금 생각이 바뀌었다면 예전 로그를 현재의 결론에 맞게 바꾸기보다, 새 notes/ 노트에서 해석을 이어가는 편이 낫다. 잘못 판단했던 기록도 그때의 상태로 남아 있을 때 회고의 재료가 된다.\n그렇다고 임시 메모를 전부 log/에 넣는 것은 아니다. 아직 판단하지 않은 기록은 먼저 inbox/에 둔다. 검토가 끝나면 sources/, log/, notes/ 중 맞는 자리에 새 정본을 만들고 원래 캡처와 연결한다. 캡처의 독립 가치가 없다면 참조를 확인한 뒤 삭제한다. 사건의 맥락 자체를 보존할 이유가 있을 때만 로그가 된다.\n프로젝트가 끝났을 때도 같은 기준을 적용한다. 당시의 회의록과 진행 기록은 log/에 남기고, 다른 맥락에서도 다시 쓸 원칙이나 설명만 별도의 notes/로 새로 추출해 기록과 연결한다. 프로젝트 MOC는 종료됐다는 이유만으로 자동 아카이브하지 않는다. 더는 고치지 않지만 관심 영역의 탐색·회고에 유용할 때만 state: archived로 동결한다. 기록과 재사용할 지식을 한 파일에서 계속 섞지 않는 것이 중요하다.\nnotes/에서 내 생각을 다시 쓴다 notes/는 내가 쓰고 앞으로도 고칠 글을 둔다. 외부 자료를 읽고 내 말로 정리한 설명, 여러 경험에서 공통으로 발견한 원칙, 반례가 생길 때마다 다듬을 개념이 여기에 해당한다.\n이 노트들은 한 번 완성하고 닫는 문서가 아니다. 새로운 근거를 만나면 같은 노트로 돌아가 문장을 고치고, 예외를 붙이고, 더 이상 맞지 않는 내용을 걷어낸다. 계속 참조할 생각을 매번 새 파일로 만들면 비슷한 정본이 여러 개 생기기 때문이다.\n예를 들어 어떤 글에서 “장애 원인은 이것이다”라는 설명을 읽었다고 해보자. 원문은 sources/에 보존하고, 그때 실제로 겪은 장애나 회의의 판단은 log/에 남긴다. 여러 사례에 적용할 수 있는 원칙으로 정리하고 싶다면 notes/에서 내 말로 다시 쓴다. 세 기록은 같은 주제를 다루지만, 앞으로 어떻게 다룰지가 다르다.\nwikilink는 관계를 문장으로 남긴다 태그는 “어느 주제로 다시 찾을까?”에 답한다. 반면 wikilink는 “무엇과 어떤 의미로 이어지는가?”에 답한다. 그래서 모든 링크를 목록처럼 모아 두기보다, 링크가 필요한 문장 안에 맥락과 함께 건다.\n세션을 서버에 두지 않으면 [[statelessness-in-system-design|세션 상태를 외부 저장소로 분리해야 한다]]. 이렇게 쓰면 링크 대상의 제목을 억지로 문장에 끼워 넣지 않아도 된다. 링크를 따라간 사람도 두 노트가 단순히 같은 단어를 공유해서 연결된 것이 아니라, 어떤 판단으로 이어졌는지 알 수 있다.\n고유명사와 개념은 wikilink가 잘하는 대상이다. Kubernetes가 등장했다는 이유로 kubernetes 태그를 하나 더 만드는 대신 [[Kubernetes]]로 연결하면, 그 문장에서 Kubernetes가 원인인지 사례인지 적용 대상인지 설명할 수 있다. 다른 이름을 쓰는 대상은 aliases로 연결할 수도 있다.\n다만 “같은 주제면 무조건 wikilink”라는 규칙도 만들지 않는다. 여러 맥락을 가로지르는 주제를 반복해서 검색하려면 태그가 더 적합하다. 반대로 연결할 의미가 없는 원문 노트에는 링크가 없어도 정상이다. 링크의 수보다 다음에 읽을 때 관계를 이해할 수 있는지가 중요하다.\n처음 만들 자리를 질문으로 정한다 새 기록을 만났을 때는 노트의 종류를 맞히려 하지 않고, 처음 만들 자리를 정하기 위해 다음 질문을 순서대로 묻는다.\n질문 답 둘 곳과 이후의 취급 아직 판단하지 않았나? 예 inbox/에서 검토하고 30일 안에 처리한다 판단이 끝났다면 외부에서 들어온 자료인가? 예 sources/에 원문과 출처를 보존한다 내가 만든 내용이라면 나중에 계속 고칠 것인가? 아니오 log/에 당시의 상태로 남기고 쌓는다 내가 만든 내용이라면 나중에 계속 고칠 것인가? 예 notes/에서 새 근거와 반례에 따라 갱신한다 그다음에 다른 노트와 의미 있는 관계가 있으면 본문 안에 wikilink를 만든다. 같은 주제를 자주 함께 읽게 되면 atlas/에 MOC를 만들고, 각 링크를 왜 읽는지 적는다. 폴더는 파일의 취급 방식을 정하고, 링크와 MOC는 파일을 옮기지 않고 다른 읽는 길을 만든다.\n가령 Kubernetes 장애를 조사한다고 해보자. 공식 문서의 설명은 sources/, 장애 당시의 회의와 판단은 log/00월00일-장애리포트.md, 여러 장애에 공통으로 적용할 원칙은 notes/에 둔다. notes/의 문장 안에서 [[Kubernetes]]와 관련 개념을 연결하고, 반복해서 읽을 필요가 생겼을 때만 MOC를 만든다. 하나의 노트에 모든 역할을 넣지 않아도 정보 사이의 연결은 오히려 더 선명해진다.\n분리한다고 연결이 끊기지는 않는다 예전에는 폴더를 나누면 서로 다른 장소로 흩어지는 것 같았다. 지금은 반대로 생각한다. 원문과 기록과 해석을 한 파일에 섞어 두면 무엇을 고쳐도 되는지부터 다시 판단해야 한다. 역할을 분리하면 각 노트의 수명과 책임이 분명해진다.\nsources/는 다른 사람의 말을 지키고, log/는 그때의 나를 남기고, notes/는 지금의 내가 계속 고친다. wikilink는 그 사이의 의미 있는 관계를 문장으로 잇는다. 노트의 공간 축이 파일의 자리를 정하고, 노트의 시간 축이 관심이 언제 돌아오고 닫히는지를 살핀다면, 이 글은 실제 기록을 어디에 보존하고 어떻게 이어갈지에 대한 이야기다.\n결국 노트 시스템은 모든 것을 한 번에 설명하는 분류표가 아니었다. 원문은 현재의 생각에 맞게 고치지 않고, 기록은 나중의 결론으로 덮어쓰지 않고, 내 생각만 다음 근거에 맞춰 고치는 것. 지금의 나는 이 구분이 시간을 꽤 많이 돌려준다고 생각한다.\n","permalink":"https://blog.yoonho.site/sources-log-wikilink/","summary":"\u003cp\u003e옵시디언에 메모를 쌓다 보면 비슷해 보이는 세 가지를 한곳에 넣고 싶어진다. 읽은 글의 내용, 당시 있었던 일, 그리고 그 둘을 연결한 내 생각이다. 나도 예전에는 이것을 한 노트에 담고 태그를 많이 붙이면 나중에 찾을 수 있다고 생각했다.\u003c/p\u003e","title":"원문은 보존하고, 기록은 쌓고, 생각은 연결한다"},{"content":"옵시디언을 처음 쓸 때는 링크가 많을수록 노트 시스템이 좋아진다고 생각했다. 일단 옵시디언에서 그래프뷰를 켜는 순간 간지가 좔좔 흐른다. 관련 있어 보이는 단어를 만나면 일단 [[링크]]로 만들었다. 그래프가 빽빽해지는 것도 그럴듯해 보였다.\n그런데 나중에 링크를 따라가 보니 왜 이어 놓았는지 알 수 없는 경우가 많았다. 같은 주제라는 이유만으로 연결한 노트도 있었고, 링크 목록은 길지만 어디서부터 읽어야 할지는 더 모호해졌다.\n지금은 위키링크와 MOC에 서로 다른 질문을 맡긴다.\n위키링크는 “무엇과 어떤 의미로 이어지는가?”에 답한다. MOC는 “어떤 순서와 관점으로 읽을 것인가?”에 답한다. 둘 다 노트를 연결하지만, 링크는 관계를 만들고 MOC는 길을 만든다.\n블로그의 다른 글 속성과 태그, 노트 정보를 표현하는 두 층옵시디언에서 Properties는 기계가 읽을 최소 구조를, tags는 여러 맥락을 가로지르는 주제를 표현하도록 나눈 기준을 정리했다. 2026. 09. 01#pkm ↗ 위키링크는 주제 표지가 아니라 참조다 위키링크는 같은 주제의 노트를 기계적으로 묶는 태그가 아니다. 내용을 복사하지 않고 하나의 대상을 여러 맥락에서 참조하면서, 두 생각이 어떤 관계인지 문장 안에 남기는 도구다.\n세션을 서버에 두지 않으면 [[statelessness-in-system-design|수평 확장]]이 쉬워진다. 이 링크는 두 노트가 모두 시스템 설계에 관한 글이라는 표시가 아니다. 무상태성이 수평 확장을 가능하게 한다는 관계를 현재 문장이 설명한다. 링크 대상의 제목에 맞춰 문장을 비틀기보다, 이 문맥에서 그 대상이 맡는 역할을 드러내는 편이 낫다.\n사람·조직·제품·기술·사건처럼 반복해서 참조할 대상은 고유명사 노트를 만들고 링크한다. aliases를 두면 다른 이름으로도 같은 대상에 닿을 수 있고, 링크되지 않은 언급을 찾기도 쉬워진다.\n하지만 모든 명사를 노트로 만들지는 않는다. 같은 주제라는 이유만으로 모든 글을 서로 잇지도 않는다. 반복해서 생각하거나 근거·대조·전제로 사용할 관계만 연결한다. 외부 원문을 보존하는 sources/ 노트에는 의미 있는 관계가 없다면 링크가 없어도 괜찮다.\n새 성질은 새 노트와 링크로 표현한다 공간축 글에서 정한 원칙은 “노트의 이주는 없다”다. 노트의 성질이 달라져 다른 폴더가 필요해져도 기존 파일을 옮기지 않는다.\nsource를 읽고 내 해석이 생기면 새 notes/ 글에서 source를 근거로 링크한다. log에서 재사용할 원칙을 발견하면 새 notes/ 글을 만들고 당시 기록을 링크한다. inbox 캡처를 검토해 정본을 만들면 새 노트와 캡처의 관계를 확인한 뒤 캡처를 남기거나 삭제한다. 이렇게 하면 외부 자료, 당시 기록, 현재의 해석이 서로 덮어쓰이지 않는다. 각각의 정본은 자기 자리에 남고, 사고의 흐름은 링크로 이어진다. 원문·기록·해석을 나누는 기준은 sources, log, wikilink 글에서 더 자세히 다뤘다.\nMOC는 링크 위의 읽기 경로다 태그와 검색은 무엇이 있는지 보여 준다. 하지만 무엇부터 읽고, 어느 지점에서 반례를 보고, 어떤 사례로 넘어갈지는 알려 주지 않는다. 그때 atlas/에 MOC(Map of Content)를 만든다.\nMOC의 각 링크에는 그 경로에서 왜 읽는지 한 줄을 쓴다.\n- [[핵심 개념]] — 이 경로의 전제를 확인한다. - [[반례]] — 전제가 깨지는 조건을 확인한다. - [[적용 기록]] — 실제 상황에서 어떻게 작동했는지 본다. 이유 없는 링크 목록은 검색 결과와 크게 다르지 않다. MOC는 색인이 아니라 지도이다. 읽기 시작할 지점을 고르고, 현재 내 위치를 알려주고, 관점이 갈라지는 곳을 보여 준다.\n하나의 노트가 여러 MOC에 나타나도 괜찮다. 파일을 복제하는 것이 아니라 읽는 목적이 다른 것이다. 같은 노트를 투자 MOC에서는 의사결정 기준으로, AI MOC에서는 자동화 사례로 연결할 수 있다. 각 MOC에서 그 노트를 왜 읽는지만 다르게 적으면 된다. MOC끼리도 상위·동료 경로로 이어질 수 있다.\n동결은 가치 없음이라는 뜻이 아니다 MOC에도 시간축의 오른쪽 끝이 있다. 다만 프로젝트가 끝났다고 자동으로 state: archived를 붙이지는 않는다.\n계속 고칠 읽기 경로라면 state 없이 유지한다. 더는 고치지 않지만 관심 영역의 탐색·회고에 유용하다면 state: archived로 동결한다. 탐색 가치도 없다면 먼저 참조를 정리하고 삭제한다. 잘못된 생각이나 정보였다는 사실이 유용하다면 잘못된 이유만 짧게 남긴 정정 노트로 축소한다. archived는 버려진 지도라는 뜻이 아니다. 현재의 관심 영역 안에 남겨 두되, 더 이상 고치지 않기로 한 경로다. 프로젝트 종료, 동결, 삭제는 같은 사건이 아니다.\n노트를 지우기 전에는 참조하는 쪽을 먼저 고친다. 원문 근거가 있다면 링크를 URL로 바꾸고, 다른 정본이 생겼다면 그쪽으로 연결한다. 삭제는 그래프에서 파일 하나를 없애는 일보다 그 파일이 맡고 있던 관계를 정리하는 일에 가깝다.\n링크 수보다 다시 읽을 이유가 중요하다 예전에는 링크가 많으면 노트가 잘 연결됐다고 생각했다. 지금은 그 링크를 따라갈 때 관계를 이해할 수 있는지를 먼저 본다.\n같은 주제를 모으고 싶다면 태그를 쓴다. 특정 대상과 생각의 관계를 남기고 싶다면 위키링크를 쓴다. 여러 관계를 어떤 관점과 순서로 읽을지 안내해야 한다면 MOC를 만든다.\n결국 연결은 수가 아니라 이유다. 문장 안의 링크가 관계를 설명하고, MOC의 한 줄이 읽는 목적을 설명한다면 그래프가 성기더라도 다시 쓸 수 있다. 내가 원하는 노트 시스템은 많이 이어진 시스템보다, 왜 이어졌는지 기억할 수 있는 시스템에 더 가깝다.\n","permalink":"https://blog.yoonho.site/obsidian-wikilinks-moc/","summary":"\u003cp\u003e옵시디언을 처음 쓸 때는 링크가 많을수록 노트 시스템이 좋아진다고 생각했다. \u003cem\u003e일단 옵시디언에서 그래프뷰를 켜는 순간 간지가 좔좔 흐른다.\u003c/em\u003e\n관련 있어 보이는 단어를 만나면 일단 \u003ccode\u003e[[링크]]\u003c/code\u003e로 만들었다. 그래프가 빽빽해지는 것도 그럴듯해 보였다.\u003c/p\u003e","title":"위키링크와 MOC로 노트 관계 잇기"},{"content":"옵시디언을 쓰면서 한동안 속성(Properties)을 꽤 많이 만들었다. 노트의 종류, 상태, 신뢰도, 분야까지 적어두면 나중에 무엇이든 골라낼 수 있을 것 같았다. 태그도 비슷했다. 관련 있어 보이는 단어는 일단 붙였다.\n그런데 노트가 늘어나자 반대의 일이 생겼다. 같은 사실을 폴더와 속성에 두 번 적었고, 태그와 링크는 서로 같은 대상을 가리켰다. 기준이 조금만 바뀌어도 여러 곳을 함께 고쳐야 했다. 결국 분류는 많아졌는데 다시 찾기는 더 어려워졌다.\n지금은 같은 YAML 안에 보이는 속성과 태그도 서로 다른 층으로 나눈다.\nProperties는 기계가 읽고 정렬·필터할 최소한의 구조를 담는다. tags는 여러 맥락을 가로지르며 다시 찾을 주제를 표시한다. 내가 세운 규칙의 출발점은 단순하다. 한 사실은 한 곳에만 적는다.\n앞의 공간축 글이 파일의 자리를 정한다면, 여기서는 그 파일 위에 어떤 구조 정보와 주제 정보를 남길지 다룬다. 위키링크와 MOC가 담당하는 관계와 읽기 경로는 다음 글로 분리했다.\n블로그의 다른 글 내 라이프사이클에 맞는 노트 시스템을 찾는 과정여러 노트테이킹 방법을 써 보며 겪은 실패와, 옵시디언에서 계속 쓰기 위해 세운 기준을 정리했다. 2026. 08. 20#pkm ↗ Properties는 노트를 설명하는 설문지가 아니다 처음에는 속성이 많을수록 노트를 잘 설명한다고 생각했다. type, status, confidence, domain 같은 값을 만들었다. 문제는 설명을 잘하는 것과 실제로 다시 쓰는 것이 다르다는 데 있었다.\n예를 들어 노트 종류를 type: source라고 적으면서 파일도 sources/에 둔다면 같은 사실이 두 곳에 있다. 처음에는 일치하더라도 언젠가는 한쪽만 바뀐다. 실제로 속성값이 비거나 폴더와 어긋난 노트가 쌓였다. 아무도 그 값으로 목록을 만들지 않는다면 관리 비용만 남는다.\n그래서 지금 기본 Properties는 네 개만 쓴다.\n--- created: 2026-09-01 tags: [] sources: - https://example.com/ aliases: - 다른 이름 --- created와 tags는 필수다. sources와 aliases는 필요할 때만 쓴다. 값이 없다면 빈 배열까지 남기지 않는다. 예외적으로 더는 고치지 않지만 관심 영역의 탐색·회고 경로로 남길 atlas/ MOC에만 state: archived를 쓴다.\n속성은 프론트매터 YAML에만 쓴다. 인라인 key:: value는 쓰지 않는다. 같은 property 이름은 볼트 전체에서 같은 타입을 유지하고, tags는 언제나 배열로 적는다. 타입이 섞이면 Bases의 필터부터 어긋나기 때문이다.\n여기서 중요한 것은 개수가 아니라 성격이다. Properties에는 정렬하거나 필터할 때 실제로 쓸 값만 둔다. 원문의 제목과 저자처럼 본문에서 읽는 편이 자연스러운 정보, 확신이 낮다는 판단, 프로젝트의 다음 행동까지 모두 YAML에 올리지 않는다. 시간축의 점·선분·반직선도 사고를 위한 비유이지 저장할 type이나 status가 아니다. 속성은 노트의 모든 특징을 요약하는 설문지가 아니라, 반복해서 계산할 작은 스키마다.\ntags는 여러 노트를 가로지르는 주제다 태그는 “이 노트를 어느 주제로 다시 찾을까?”에만 답한다. 내 규칙은 다음과 같다.\n0~3개만 쓴다. 소문자 영문 kebab-case를 쓴다. 계층 태그는 만들지 않는다. 폴더명, 노트 종류, 상태를 복제하지 않는다. 본문에 #해시태그를 쓰지 않는다. 적어도 세 노트를 같은 이유로 다시 찾을 때만 새 태그를 만든다. 가장 자주 걸리는 기준은 그 노트가 정말 그 태그에 관한가라는 질문이다. Kubernetes 배포 중 장애를 다룬 노트라면 reliability는 주제가 될 수 있다. 하지만 그 글에 개발 도구가 등장했다는 이유만으로 dev까지 붙이면 태그의 범위가 끝없이 넓어진다.\n고유명사도 태그로 만들지 않는다. #aws, #node-js, #kubernetes처럼 대상의 이름을 태그에 넣으면 그 대상이 어떤 관계로 등장했는지 알 수 없다. 그런 이름은 [[AWS]], [[Node.js]], [[Kubernetes]]처럼 링크한다.\n태그가 YAML의 Properties 안에 보인다는 점은 조금 헷갈린다. 저장 형식으로 보면 tags도 하나의 property다. 하지만 운영 역할은 다르다. created가 구조적 사실이라면 tags는 다중 소속을 표현하는 주제 필터다. 같은 화면에 있다고 같은 질문에 답하는 것은 아니다.\n태그에는 분명한 한계도 있다. 태그 하나에는 그 태그를 붙인 이유나 설명을 담기 어렵고, 태그가 많아질수록 붙이는 일과 태그로 다시 찾는 일이 모두 어려워진다. 태그와 태그 사이의 관계도 태그만으로는 문장처럼 남길 수 없다.\n태그와 위키링크는 서로 대체하지 않는다 같은 횡단 주제로 결과를 모으는 일은 태그가 잘한다. 반면 사람·조직·제품·기술·사건처럼 반복해서 참조할 대상, 또는 두 생각 사이의 구체적인 관계는 위키링크가 맡는다. 같은 주제라는 이유만으로 모든 노트를 서로 링크하지 않고, 의미 관계가 없는데도 고유명사를 태그로 만들지 않는다.\n그러므로 “태그보다 위키링크가 낫다”가 결론은 아니다. 태그는 횡단 주제, 위키링크는 의미 관계다. 위키링크를 문장 안에 남기고 MOC로 읽는 순서를 만드는 방법은 위키링크와 MOC 글에서 이어서 다룬다.\n그럼 이 정보는 어디에 적을까 정보를 어디에 적을지 고를 때는 아래 순서로 생각한다.\n저장 형식보다 나중에 어떤 질문으로 다시 찾을지를 먼저 정한다.\n예를 들어 Kubernetes에서 Node가 중단된 사건을 정리한다고 해보자.\n기록할 정보 사용할 수단 이유 노트를 만든 날짜 created property 날짜로 정렬하고 필터할 구조적 사실이다 참고한 문서 URL sources property 근거 자료를 모으는 정해진 필드다 reliability, security tags 다른 시스템과 프로젝트에도 걸쳐 다시 찾을 주제다 [[Kubernetes]], [[Node.js]] wikilink 이름 있는 대상이며 문장 안에서 관계를 설명할 수 있다 무엇이 잘못됐고 다음에는 어떻게 할지 본문 자연어로 읽고 판단해야 하는 내용이다 이렇게 나누면 하나의 정보가 두 군데에 들어가지 않는다. 주제가 추가됐다고 파일을 옮길 필요도 없고, 새로운 대상을 만났다고 태그 어휘를 늘릴 필요도 없다.\n분류가 필요해 보일 때 먼저 의심한다 새 property나 태그를 만들고 싶을 때는 기능보다 갱신 비용을 먼저 생각한다.\n기존 정보에서 계산할 수 있는가. 값의 경계가 명확한가. 앞으로도 내가 실제로 고칠 이유가 있는가. 세 질문 중 하나라도 답하기 어렵다면 새 필드를 만들지 않는다. 검색이나 Bases의 조건식으로 계산할 수 있는 것은 저장하지 않는 편이 낫다.\n태그도 마찬가지다. 같은 태그가 30개를 넘으면 태그를 더 잘게 쪼개지 않고 MOC를 만든다. 필터 결과가 많아서 읽는 순서를 잃은 문제라면 분류보다 안내가 더 필요하기 때문이다. 태그는 무엇을 모을지 정하고, MOC는 무엇부터 읽을지 안내한다.\n이 규칙은 옵시디언 기능을 적게 쓰자는 이야기가 아니다. 서로 다른 기능이 같은 일을 하지 않게 하자는 이야기다. Properties는 구조, tags는 주제를 맡긴다. 원문·당시 기록·계속 고칠 생각을 실제 폴더에서 나누는 기준은 sources, log, wikilink 글에서 이어서 정리했다. 하나의 도구가 하나의 질문에만 답하면 규칙도 짧아지고, 어긋날 곳도 줄어든다.\n결국 노트 시스템은 분류를 잘했다는 만족감을 주기보다 시간을 돌려줘야 한다. 기록할 때 덜 망설이고, 다시 찾을 때 이유를 이해하고, 고칠 곳이 하나만 남는 것. 지금의 나는 그 정도면 충분하다고 생각한다.\n","permalink":"https://blog.yoonho.site/obsidian-properties-tags-wikilinks/","summary":"\u003cp\u003e옵시디언을 쓰면서 한동안 속성(Properties)을 꽤 많이 만들었다. 노트의 종류, 상태, 신뢰도, 분야까지 적어두면 나중에 무엇이든 골라낼 수 있을 것 같았다. 태그도 비슷했다. 관련 있어 보이는 단어는 일단 붙였다.\u003c/p\u003e","title":"속성과 태그, 노트 정보를 표현하는 두 층"},{"content":"노트를 쓰다 보면 결국 이 질문을 만나게 된다.\n“이 노트는 어디에 두어야 하지?”\n나도 이 질문 때문에 폴더를 꽤 자주 바꿨다. 개발 폴더를 만들었다가 프로젝트 폴더로 옮기고, 생산성에 관한 노트인지 PKM에 관한 노트인지 고민했다. 새 구조를 만들 때마다 이번에는 오래 쓸 수 있을 것 같았다. 그런데 노트가 늘어나면 경계가 다시 흐려졌다.\n지금 생각하면 폴더가 부족했던 것이 아니다. 폴더에 너무 많은 질문을 맡기고 있었다.\n공간을 주제로 나눈 것이 문제였다 파일은 동시에 여러 폴더에 있을 수 없다. 하나의 노트에는 하나의 경로만 있다.\n그런데 주제는 그렇지 않다. 옵시디언 보안 설정을 정리한 노트가 있다고 해보자. 이 노트는 obsidian에 관한 글이면서 security와 privacy에도 걸쳐 있을 수 있다. 주제로 폴더를 나누면 셋 중 하나를 골라야 한다.\n복사해서 여러 곳에 둘 수도 있다. 그러면 곧 다른 문제가 생긴다. 어느 파일이 정본인지, 어디를 고쳐야 하는지 판단해야 한다. 파일을 하나만 남기면 선택하지 않은 주제로 들어오는 길이 끊긴다.\n폴더에 넣기 어려운 노트가 계속 생긴다면 분류가 덜 세밀해서가 아닐 수 있다. 애초에 여러 답을 가질 수 있는 질문을, 하나의 답만 허용하는 도구에 맡긴 것일 수 있다.\n블로그의 다른 글 내 라이프사이클에 맞는 노트 시스템을 찾는 과정여러 노트테이킹 방법을 써 보며 겪은 실패와, 옵시디언에서 계속 쓰기 위해 세운 기준을 정리했다. 2026. 08. 20#pkm ↗ 폴더는 하나의 질문만 답한다 그래서 공간 축을 다시 정했다. 주제가 아니라 이 노트를 어떻게 취급할 것인가를 폴더가 답하도록 했다.\n내 볼트에서는 노트가 어디에서 왔고 앞으로 어떻게 다룰지에 따라 자리를 나눈다.\n공간 묻는 질문 다루는 방식 inbox/ 아직 판단하지 못했나? 빠르게 붙잡고 검토한 뒤 비운다 notes/ 내 생각과 경험에서 나왔나? 내 언어로 계속 다듬는다 sources/ 남이 쓴 내용인가? 출처와 원문 맥락을 보존하고 본문은 고치지 않는다 log/ 그때의 사건과 판단을 남길 것인가? 당시 상태를 보존하고 고치지 않고 쌓는다 atlas/ 여러 노트를 잇는 지도인가? 링크마다 이유를 적고 목적에 맞는 읽기 경로를 만든다 이 기준도 완벽한 분류법은 아니다. 다만 security인가?, privacy인가? 보다 답하기 쉽고, 시간이 지나도 비교적 덜 흔들린다. 주제는 계속 늘고 하나의 노트가 여러 주제와 관련되지만, 노트가 어디에서 왔고 앞으로 어떻게 취급할지는 더 적은 선택지로 남기 때문이다.\n폴더는 노트가 실제로 놓이는 한 위치다. 태그·위키링크·MOC는 그 파일을 복제하지 않고도 다른 관점에서 다시 보게 한다.\n주제는 위치가 아니다 여기서 중요한 것은 폴더를 줄이는 것만이 아니다. 폴더가 내려놓은 질문을 다른 수단에 정확히 나눠줘야 한다.\n태그는 “어느 주제로 다시 찾을까?”에 답한다. 한 노트에 여러 태그를 붙일 수 있으니 다중 소속을 표현하기 좋다. 다만 태그가 많아지면 다시 분류 체계가 되기 때문에, 실제로 함께 볼 가치가 있는 횡단 주제만 남긴다.\n위키링크는 “무엇과 어떤 의미로 이어질까?”에 답한다. Node.js나 Kubernetes처럼 이름이 있는 대상은 태그보다 링크가 자연스럽다. 중요한 것은 링크의 수가 아니라 왜 연결했는지를 문장 안에 남기는 일이다.\n속성과 태그를 실제로 어떻게 나눠 쓰는지는 속성과 태그 글에서, 의미 관계와 읽기 경로를 만드는 방법은 위키링크와 MOC 글에서 이어서 정리했다. 원문·당시 기록·내 생각을 실제로 나누는 기준은 sources, log, wikilink 글에서 더 자세히 다뤘다.\nMOC(Map of Content)는 “어떤 순서로 읽을까?”에 답한다. 검색 결과를 한 번 더 나열하는 색인이 아니라, 읽기 시작점과 관점이 갈리는 곳을 보여 주는 지도다. 링크마다 그 경로에서 왜 읽는지 적는다. 같은 노트가 여러 MOC에 연결되어도 파일은 여전히 하나다.\n노트의 이주는 없다 공간축을 정리하면서 가장 오래 남은 문제는 inbox/였다. 검토가 끝난 캡처를 sources/, notes/, log/ 중 어디로 옮길지 정하면 되는 것처럼 보였다. 그런데 파일 이동에 의미를 맡기면 한 파일이 성질까지 바꾸는 셈이 된다.\n지금은 더 단순하게 생각한다. 노트의 이주는 없다. 성질이 달라져 다른 폴더가 필요하다면, 달라진 성질에 맞는 노트를 그 자리에 새로 만든다.\n검토 전 캡처는 inbox/에 남기고, 채택한 생각은 notes/에 새로 쓴다. 외부 원문은 sources/에 남기고, 그 원문에 대한 내 해석은 notes/에 새로 쓴다. 프로젝트의 당시 기록은 log/에 남기고, 반복해서 쓸 원칙은 notes/에 새로 추출한다. 새 노트와 이전 노트는 위키링크로 이어 둔다. 이전 캡처가 변화 과정이나 출처를 보여 줄 가치가 있다면 남기고, 독립적인 가치가 없다면 참조를 확인한 뒤 삭제한다. 주제가 바뀌었다는 이유만으로 파일을 옮기거나 복제하지 않는다. 주제의 추가·삭제는 태그와 링크의 일이지 파일 이동의 이유가 아니다.\n이 원칙에서 가장 조심할 곳은 inbox/다. 인박스는 아직 정하지 못한 것을 받기 때문에 쉽게 창고가 된다. 30일 안에 검토하고, 맞는 자리에 새 정본을 만들거나 버린다. 인박스 파일 자체를 오래 보관하는 것으로 결정을 미루지 않는다.\n폴더가 단순해지니 쓰는 일이 남았다 예전에는 애매한 노트를 만날 때마다 새 폴더가 필요하다고 생각했다. 지금은 질문을 바꾼다.\n이 노트를 어떻게 다룰 것인가. 어느 주제로 찾고 싶은가. 무엇과 연결되는가. 어떤 순서로 다시 읽을 것인가.\n각 질문을 폴더, 태그, 위키링크, MOC가 하나씩 맡으면 구조를 크게 고칠 일이 줄어든다. 새 주제가 생겨도 폴더를 추가할 필요가 없고, 하나의 노트가 여러 관심사에 걸쳐 있어도 복사본을 만들지 않는다. 파일의 자리는 하나지만, 의미 있는 관계는 문장 안에서 여러 방향으로 이어질 수 있다.\n결국 내가 원한 것은 모든 노트를 완벽하게 설명하는 폴더 구조가 아니었다. 노트를 쓸 때 망설이지 않고, 나중에 고칠 곳이 하나뿐인 구조였다.\n공간 축은 노트의 의미 전체를 설명하지 않는다. 그저 이 파일을 어떻게 취급할지 정한다. 오히려 그 정도만 맡길 때 폴더는 오래 쓸 수 있는 도구가 되는 것 같다.\n","permalink":"https://blog.yoonho.site/note-spatial-axis/","summary":"\u003cp\u003e노트를 쓰다 보면 결국 이 질문을 만나게 된다.\u003c/p\u003e\n\u003cp\u003e“이 노트는 어디에 두어야 하지?”\u003c/p\u003e\n\u003cp\u003e나도 이 질문 때문에 폴더를 꽤 자주 바꿨다. 개발 폴더를 만들었다가 프로젝트 폴더로 옮기고, 생산성에 관한 노트인지 PKM에 관한 노트인지 고민했다. 새 구조를 만들 때마다 이번에는 오래 쓸 수 있을 것 같았다. 그런데 노트가 늘어나면 경계가 다시 흐려졌다.\u003c/p\u003e","title":"노트는 어디에 있어야 할까"},{"content":"노트테이킹과 PKM(Personal Knowledge Management)을 제대로 해보고 싶었다. 좋은 생각을 잊지 않고, 읽은 것을 내 것으로 만들고, 진행 중인 일도 조금 더 잘 관리하고 싶었다.\n그래서 여러 방법을 써봤다. Zettelkasten, PARA method, SecondBrain CODE, LLM-WIKI 등등. 각각은 분명히 설득력 있었다. 그런데 모두를 그대로 내 생활에 가져오면 오래가지 못했다.\n어떤 방법은 너무 자주 정리해야 했고, 어떤 방법은 기록하는 것보다 구조를 설계하는 데 더 많은 시간을 쓰게 만들었다. 결국 내게 필요한 것은 완벽한 노트테이킹 기법 하나가 아니라, 각 방법이 풀려는 문제를 이해하고 필요한 부분만 가져오는 일이었다.\n이 글은 내가 겪은 실패를 정리하는 글이기도 하다. 같은 실수를 반복하지 않기 위해서다.\nInbox: 일단 잃어버리지 않기 가장 먼저 필요했던 방식은 인박스다. Zettelkasten에서는 fleeting notes라고 한다. 떠오른 생각, 읽다가 저장하고 싶은 문장, 나중에 볼 링크를 한곳에 빠르게 넣는다.\n인박스의 목적은 정리가 아니라 놓치지 않는 것이다.\n처음에는 메모를 만들 때마다 태그를 붙이고, 적절한 디렉터리를 골랐다. 그런데 생각보다 이것이 큰 마찰이었다. “이건 개발인가, 생산성인가, 글감인가?” 같은 질문에 답하는 사이에 메모할 이유가 사라졌다.\n그래서 인박스는 좋았다. 지금은 적고, 분류는 나중에 한다. 적어도 생각을 놓치지는 않으니까.\n문제는 인박스가 쌓이기 시작한 다음이다. 인박스만 믿으면 결국 다시 찾지 못하는 메모 창고가 된다. 인박스는 노트를 보관하는 곳이 아니라, 정리되지 않은 생각이 잠시 머무는 곳이어야 했다.\n불릿 저널: 오늘을 운영하기 불릿 저널(Bullet Journal)은 할 일, 일정, 짧은 기록을 빠르게 남기는 방식이다. 오늘 해야 할 일과 오늘 있었던 일을 같은 흐름에서 볼 수 있다.\n이 방법의 목적은 현재를 운영하는 것이다.\n긴 회고를 남기지 않더라도, 짧은 기록이 쌓이면 내가 시간을 어디에 썼는지 알 수 있다. 완료하지 못한 일도 자연스럽게 다음 날로 넘어간다. 복잡한 작업 관리 시스템보다 오히려 계속 쓰기 쉬웠다.\n불릿 저널의 경우 아날로그 노트에서는 아직도 잘 쓰고 있다.\n그런데 시간 순서로 쌓이는 기록에는 한계가 있다. 몇 달 전에 읽은 글에서 얻은 생각이나, 특정 주제에 관한 메모를 다시 찾으려면 일간 노트를 계속 뒤져야 한다. 그래서 주기적으로 노트에 적은 내용을 컴퓨터로 옮겨줘야 한다.\n그래서 불릿 저널은 지식을 쌓는 방식이라기보다, 오늘을 잊지 않고 운영하는 방식으로 보는 편이 맞았다. 그래서 불릿 저널은 인생을 관조하는 목적에 적합했다.\n외부 링크 https://bulletjournal.com/blogs/faq https://bulletjournal.com/blogs/faq ↗ PARA: 정보와 프로젝트를 연결하기 PARA는 Projects, Areas, Resources, Archives로 정보를 나누는 방식이다. 진행 중인 프로젝트, 계속 관리할 영역, 참고 자료, 끝난 자료를 구분한다.\n이 방법의 목적은 정보를 지금 하는 일에 붙이는 것이다.\n프로젝트에는 끝나는 시점이 있다. 블로그 글 하나를 쓰는 일, 여행을 준비하는 일, 새로운 것을 공부하는 일이 그렇다. 반면 건강이나 재무처럼 끝나지 않는 일도 있다. PARA는 이런 차이를 구조에 반영한다.\n문제는 이 구조를 너무 엄격하게 지키려 했다는 것이다. 어떤 노트는 프로젝트이면서 리소스였고, 시간이 지나면 영역이 되기도 했다. 나는 “이 노트는 어디에 있어야 하지?”라는 질문을 너무 오래 붙잡았다.\n그 결과 디렉터리 구조를 자주 바꿨다. 처음에는 더 나은 구조를 찾는 일처럼 보였다. 그런데 노트를 쓸수록 구조를 손보는 일이 반복됐다. 지금 생각하면 정보를 잘 관리한 것이 아니라, 분류 체계를 계속 다시 만들고 있었던 것 같다.\nPARA에서 가져갈 것은 네 개의 폴더가 아니라, 지금 필요한 정보를 쉽게 찾자는 기준이었다.\n외부 링크 https://fortelabs.com/blog/para/ https://fortelabs.com/blog/para/ ↗ 제텔카스텐: 생각을 연결하기 제텔카스텐(Zettelkasten)은 하나의 노트에 하나의 생각을 담고, 다른 노트와 연결하면서 지식을 쌓는 방식이다.\n이 방법의 목적은 정보를 모으는 것이 아니라 생각 사이의 연결을 만드는 것이다.\n처음에는 모든 노트를 작게 나누고, 링크를 많이 만들수록 좋은 시스템이라고 생각했다. 노트끼리 이어지는 모습은 꽤 그럴듯했다. 그래프 화면도 멋있었다. 문제는 링크가 많다고 생각이 깊어지는 것은 아니라는 점이다.\n인용문과 링크만 남긴 노트는 나중에 봐도 내가 왜 저장했는지 알기 어려웠다. 반대로 짧더라도 내 말로 적은 노트는 시간이 지나도 다시 생각할 거리를 남겼다.\n제텔카스텐에서 내게 남은 것은 복잡한 연결 규칙이 아니다. 오래 생각할 가치가 있는 내용이라면, 왜 중요했는지 내 말로 적고 다른 생각과 연결해 본다는 습관이다.\n다만 모든 메모를 이렇게 만들 필요는 없다고 생각한다. 장보기 목록이나 회의 중 할 일까지 하나의 생각으로 다듬기 시작하면 노트테이킹 자체가 일이 된다.\n외부 링크 https://zettelkasten.de/introduction/ https://zettelkasten.de/introduction/ ↗ ACE를 상위 렌즈로 사용하기 최근에는 ACE 프레임워크도 다시 살펴봤다. ACE는 Atlas, Calendar, Efforts의 약자다. 지식과 아이디어는 Atlas에, 시간의 흐름에 따라 남는 기록은 Calendar에, 지금 행동이 필요한 일은 Efforts에 둔다.\n내가 겪었던 문제와 맞닿는 부분이 있었다. 태그와 디렉터리로 모든 노트를 한 번에 분류하려 했던 대신, ACE는 노트의 주제보다 지금 어떤 맥락에서 다시 열 노트인지에 주목한다. 다만 세 개의 폴더를 새로 만들라는 뜻으로 받아들이지는 않기로 했다. 내 볼트에서는 ACE를 기록을 넣기 전에 던지는 질문으로 사용한다.\nAtlas는 오래 남길 지식과 생각을 이해하고 재사용하는 관점 Calendar는 회의록이나 사건처럼 시간과 함께 쌓이는 기록의 관점 Efforts는 프로젝트와 진행 중인 일을 실제 행동으로 옮기는 관점 특히 옵시디언에서는 이 구분이 꽤 실용적으로 보인다. 빠르게 적은 기록을 모두 지식 노트로 다듬을 필요는 없고, 프로젝트의 실행 맥락과 오래 남길 생각을 같은 파일에서 억지로 관리하지 않아도 된다. 현재 구조에서는 판단 전 기록을 inbox/, 남의 원문을 sources/, 당시 사건을 log/, 계속 고칠 내 글을 notes/에 둔다.\nACE는 새로운 정답이라기보다, 지금 이 기록을 이해·회고·실행 중 어떤 목적으로 다시 열 것인지 묻게 하는 렌즈에 가깝다. 그 질문이 현재의 폴더와 충돌하지 않고, 오히려 처음 기록할 때의 결정 비용을 줄여 주는지 계속 사용하며 확인하려 한다.\nACE가 흥미로운 이유는 새로운 폴더 구조 때문이 아니라, 지식·시간·행동이 서로 다른 종류의 재사용 맥락이라는 점을 다시 생각하게 만들기 때문이다.\n외부 링크 https://blog.linkingyourthinking.com/notes/ace-folder-framework https://blog.linkingyourthinking.com/notes/ace-folder-framework ↗ 한눈에 비교해 보면 방법 해결하려는 문제 핵심 기준 내게 맞았던 점 주의할 점 Inbox 떠오른 생각을 놓치지 않기 빠른 기록 분류 부담 없이 바로 적을 수 있다 쌓아 두기만 하면 메모 창고가 된다 Bullet Journal 오늘의 일과 기록을 관리하기 시간의 흐름 할 일과 짧은 기록을 함께 볼 수 있다 오래된 지식이나 특정 주제를 찾기 어렵다 PARA 진행 중인 일에 정보를 연결하기 행동 가능성 프로젝트에 필요한 자료를 가까이 둘 수 있다 폴더 구조를 너무 엄격하게 만들기 쉽다 Zettelkasten 생각을 연결하고 발전시키기 노트 간의 연결 글감과 생각을 내 말로 쌓을 수 있다 모든 메모를 작은 노트로 만들면 부담스럽다 ACE 지식·시간·행동의 맥락을 나누기 Atlas·Calendar·Efforts 현재 폴더 위에서 기록의 다음 사용 목적을 묻기 좋다 세 폴더를 그대로 복제하면 관리 비용이 생긴다 실패의 시작은 태그와 디렉터리였다 돌아보면 내가 반복한 실수는 세 가지였다.\n첫째, 태그를 무분별하게 사용했다. 태그가 많아질수록 기준은 흐려졌다. 비슷한 태그가 계속 생기고, 어떤 노트에는 태그를 붙이지 않게 됐다. 검색과 분류를 위해 필요한데 오히려 검색과 분류에 노이즈가 되어버렸다.\n둘째, 디렉터리 구조를 너무 자주 바꿨다. 미래의 모든 노트를 수용할 구조를 만들려고 했다. 그런데 미래의 메모는 늘 예상 밖의 모습으로 들어왔다. 결국 자주 바뀌는 구조는 좋은 구조가 아니었다.\n셋째, 목적 없이 유행을 따라갔다. 누군가의 vault 구조나 태그 체계가 좋아 보이면 바로 가져왔다. 하지만 그 방법이 해결하려던 문제와 내가 가진 문제가 같지는 않았다. 도구와 방법은 가져왔지만, 왜 필요한지는 충분히 생각하지 못했다.\n아마 노트테이킹을 좋아하는 사람이 한 번쯤 겪는 일 아닐까. 노트를 쓰기보다 노트 시스템을 만지는 시간이 늘어나는 일 말이다.\n옵시디언에서 세운 기준 여러 방법을 거치고 나서, 옵시디언에서는 특정 기법을 그대로 따르기보다 몇 가지 기준을 세우게 됐다.\n첫째, 기록할 때는 분류를 강요하지 않는다. 빠르게 남겨야 하는 것은 inbox/에 두고, 검토가 끝난 뒤에 어디에 둘지 결정한다.\n둘째, 디렉터리는 적고 안정적으로 유지한다. 폴더는 주제나 노트 종류를 설명하는 분류 체계가 아니라, 원문·당시 기록·계속 고칠 글을 어떻게 취급할지 정하는 위치여야 한다.\n셋째, sources/의 원문은 고치지 않고 log/의 당시 기록은 현재의 결론으로 덮어쓰지 않는다. 반대로 계속 사용할 내 생각은 notes/에서 같은 정본을 갱신한다.\n넷째, 태그는 여러 맥락을 가로지르는 주제에만 쓴다. 폴더와 태그가 같은 일을 하게 만들지 않는다.\n다섯째, 링크는 많이 만들기보다 이유가 있을 때 만든다. 고유명사와 개념은 문장 안에서 wikilink로 연결하고, MOC에는 각 링크를 왜 읽는지 남긴다.\n마지막으로, 노트 시스템은 계속 고치는 대상이 아니라 계속 쓰는 대상이다. 불편한 점이 생길 때만 조금씩 바꾸고, 처음부터 완벽한 구조를 만들 필요는 없다.\n결국 방법보다 목적이다 이 표를 보면 가장 좋은 방법 하나를 고르는 일보다, 지금 어떤 문제를 풀고 싶은지 먼저 아는 편이 중요해 보인다.\n나는 inbox/로 생각을 붙잡고, 불릿 저널로 오늘을 기록하고, sources/에는 남의 원문을 보존하고, log/에는 당시의 판단을 쌓고, notes/에서는 오래 남길 생각을 계속 고쳐 보려 한다. PARA는 프로젝트에 정보를 붙이는 기준으로, 제텔카스텐은 생각을 연결하는 습관으로 가져간다. ACE는 이 흐름을 시작하기 전에 이해·회고·실행 중 무엇이 필요한지 묻는 상위 렌즈로 둔다.\n결국 PKM은 정답을 복사하는 일이 아니라, 내 생활에서 계속 쓸 수 있는 기준을 만드는 일에 가깝다. 규칙을 추가하는 것보다 정리하고 덜어내는 게 중요한 순간이었다.\n원문·기록·생각을 실제로 어디에 두고 어떻게 연결하는지는 원문은 보존하고, 기록은 쌓고, 생각은 연결한다에서 이어서 정리했다.\n","permalink":"https://blog.yoonho.site/pkm-note-taking-workflow/","summary":"\u003cp\u003e노트테이킹과 PKM(Personal Knowledge Management)을 제대로 해보고 싶었다. 좋은 생각을 잊지 않고, 읽은 것을 내 것으로 만들고, 진행 중인 일도 조금 더 잘 관리하고 싶었다.\u003c/p\u003e","title":"내 라이프사이클에 맞는 노트 시스템을 찾는 과정"},{"content":"최근 작업하던 프로젝트 폴더들을 한번 훑어 봤다. 블로그도 있고, 영상 제작 도구도 있고, 작은 웹서비스와 데스크톱 앱도 있다. 하나씩 만들 때는 그저 당장 필요한 것을 고른다고 생각했는데, 모아 놓으니 반복되는 선택이 꽤 보였다.\nTypeScript를 공통 언어로 쓰고, 화면은 가능한 가볍게 배포한다. 서버가 꼭 필요해지면 Cloudflare Workers와 D1을 붙인다. React는 모든 곳에 깔지 않고, 복잡한 화면이나 영상처럼 이유가 분명할 때만 쓴다. 그리고 이제는 AI와 함께 개발하기 좋은가도 선택 기준에 들어왔다.\n그러니까 이 글은 \u0026ldquo;요즘은 이 스택이 정답이다\u0026rdquo; 같은 이야기는 아니다. 지금의 내가 몇 개 프로젝트를 만들면서 어느 정도까지의 복잡도를 감당하고 싶은지 정리한 기록에 가깝다.\n공통 언어는 TypeScript가 됐다 웹사이트, CLI, Cloudflare Functions, 영상 렌더링 파이프라인까지 TypeScript가 등장한다. 물론 모든 것을 TypeScript로 만들 수 있다는 뜻은 아니다. ssagal 프로젝트처럼 Rust와 Tauri가 더 자연스러운 경우도 있다.\n그런데 작은 서비스를 여럿 만들다 보니, 언어를 하나 더 고르는 비용이 생각보다 컸다. 문법을 다시 익히는 것보다 패키지 관리, 타입, 배포 스크립트, 에러를 찾는 방식이 제각각이 되는 쪽이 더 귀찮았다. TypeScript는 웹의 언어이기도 하지만, 나에게는 여러 프로젝트를 오갈 때의 기본 작업 언어가 된 것 같다.\n그래서 CLI와 영상 파이프라인도 TypeScript로 묶었고, Remotion 작업도 같은 흐름 위에 있다. 프론트엔드와 그 주변의 자동화 코드를 다른 세계처럼 느끼지 않아도 되는 점이 좋다.\nAI와 같이 만들 수 있는가 요즘 기술을 고를 때 AI를 빼고 생각하기는 어렵다. 코드를 처음부터 다 맡긴다는 뜻은 아니다. 구현을 시작하고, 문서를 찾고, 테스트를 만들고, 막힌 에러를 풀어 가는 과정에 이미 AI가 깊게 들어와 있다.\n그래서 프로젝트의 목표가 같은 선상에 있다면, AI가 비교적 안정적으로 읽고 쓰고 고칠 수 있는 언어와 도구를 먼저 보게 된다. 문서와 예제가 충분하고, 널리 쓰이는 패키지 생태계가 있는가도 중요해졌다. 내가 모르는 기술을 배워 가는 시간뿐 아니라, AI가 헛다리를 짚은 결과를 검증하고 바로잡는 시간도 결국 내 몫이기 때문이다.\n신생 언어나 아직 AI가 다루기 어려운 도구가 나쁘다는 이야기는 아니다. 그 도구가 아니면 만들 수 없는 것이 있다면 당연히 써야 한다. 다만 프로젝트를 완성하는 것이 목표라면, 새로운 기술이라는 이유만으로 선택 순위를 올리지는 않게 됐다. 지금은 내가 이해할 수 있고 AI와 함께 끝까지 밀고 갈 수 있는 쪽을 우선으로 둔다.\n화면은 먼저 가볍게 만든다 콘텐츠를 보여주는 화면에는 거대한 애플리케이션이 꼭 필요하지 않은 경우가 많았다.\n이 블로그는 Hugo로 정적 페이지를 만든다. 여러 기록 사이트는 Astro로 만들고, wedding 모바일 청첩장 프로젝트는 바닐라 HTML, CSS, JavaScript로 시작했다. 만드는 방식은 조금씩 달라도 공통점은 있다. 글이나 정보가 중심인 페이지는 먼저 정적으로 만들고, 배포도 최대한 단순하게 가져간다는 점이다.\n이 선택이 멋있어서라기보다, 운영해야 할 것이 줄어들기 때문이다. 서버 프로세스가 계속 살아 있는지 신경 쓰지 않아도 되고, 콘텐츠를 고친 뒤 결과를 예측하기도 쉽다. 블로그를 Ghost에서 다시 정적 사이트로 옮긴 것도 비슷한 이유였다. 기능이 많은 도구가 항상 글을 더 자주 쓰게 해 주지는 않았다.\n물론 정적 사이트가 모든 문제를 해결하지는 않는다. 로그인한 사용자의 상태를 길게 들고 가거나, 화면이 계속 바뀌는 서비스라면 다른 선택을 해야 할 것이다. 다만 처음부터 그 복잡도를 들고 시작할 이유는 많지 않았다.\n서버는 필요한 만큼만 둔다 정적 페이지로 시작해도 결국 데이터가 필요한 순간은 온다. wedding 모바일 청첩장 프로젝트의 방명록에는 저장할 곳이 필요했고, 보고서 작성 웹 앱에는 데이터와 파일, 비동기 작업이 필요했다.\n이런 경우에는 Cloudflare Pages와 Workers, D1 같은 도구가 잘 맞았다. 사이트를 배포하는 흐름에서 API를 붙일 수 있고, 작은 데이터베이스나 큐도 같은 곳에서 다룰 수 있다. 별도 서버 한 대를 먼저 열어 두고 관리하는 것보다 시작의 문턱이 낮다.\n여기에도 기준은 있다. \u0026ldquo;서버가 없다\u0026quot;가 목표는 아니다. 서버를 운영해야 할 이유가 생기기 전까지는, 운영할 서버를 만들지 않는 쪽에 가깝다. 데이터량이나 처리 시간이 커지면 이 선택도 다시 봐야 한다. 지금 규모에서는 필요한 만큼의 서버리스 기능이 가장 편했다.\nReact는 필요한 곳에만 쓴다 한동안 React는 웹 프로젝트의 기본값처럼 느껴졌다. 그런데 모든 페이지가 같은 정도의 상태 관리와 컴포넌트 조합을 요구하지는 않는다.\nReact와 Remotion은 영상 작업에서 확실히 값을 한다. 프레임, 자막, 오디오 타이밍, 시뮬레이션 결과를 컴포지션으로 조합해야 하는 영상이 있다. 또 다른 영상 파이프라인은 나레이션 길이에 맞춰 씬의 길이를 계산하고, 자막과 BGM을 맞춘다. 이 정도가 되면 UI를 선언적으로 쪼개고 재사용하는 방식이 오히려 단순해진다.\n반대로 ssagal 프로젝트는 화면 위에 작은 버튼 하나를 띄우고 소리를 재생하는 데스크톱 앱이다. 여기에는 React를 올리지 않았다. 순수 HTML, CSS, JavaScript로 화면과 재생 로직을 끝내고, Rust/Tauri는 윈도우를 만드는 일에 집중하게 했다. 프레임워크를 쓰지 않은 것도 기술을 포기한 것이 아니라, 필요한 경계를 작게 잡은 선택이었다.\n모노레포도 늘 기본값은 아니다 여러 앱이 같은 디자인 시스템이나 타입을 공유하면 모노레포는 편하다. 여러 사이트가 하나의 디자인 시스템을 공유하는 경우나, CLI·공용 스키마·외부 서비스 연동·영상 패키지가 함께 움직이는 경우에는 특히 그렇다.\npnpm workspace로 의존성을 한 번에 관리하고, 공용 코드를 패키지로 나눠 두면 바꿀 곳을 찾기가 쉬워진다. 대신 아주 작은 단일 프로젝트까지 굳이 모노레포로 만들 필요는 없다고 생각한다. 구조는 나중에 필요해졌을 때 옮길 수 있지만, 처음부터 늘어난 폴더와 설정은 계속 관리해야 하기 때문이다.\n결국은 운영할 수 있는 크기 프로젝트를 훑어 보고 나서 남은 것은 특정 프레임워크의 승패가 아니었다. 나는 TypeScript를 자주 쓰지만 Rust가 더 맞는 앱도 만들었다. 정적 사이트를 선호하지만, 데이터가 필요할 때는 Workers와 D1을 붙였다. React를 쓰기도 하고, 화면이 단순하면 쓰지 않기도 했다.\n결국 기술 스택은 기능 목록보다 내가 운영할 수 있는 복잡도의 크기로 고르게 되는 것 같다. 이제 그 안에는 AI와 함께 개발하고 검증할 수 있는가도 들어간다. 지금의 기준이 몇 년 뒤에도 그대로일지는 모르겠다. 그래도 적어도 지금은, 새 도구를 하나 더 넣기 전에 그 도구가 없으면 정말 풀리지 않는 문제가 무엇인지 먼저 보려고 한다.\n다음 글에서는 이 기준이 실제 선택으로 이어진 두 사례를 더 자세히 적어 보려고 한다. Remotion을 고른 이유와, Tauri 앱에서 React를 쓰지 않은 이유다.\n","permalink":"https://blog.yoonho.site/project-stack-retrospective-1/","summary":"\u003cp\u003e최근 작업하던 프로젝트 폴더들을 한번 훑어 봤다. 블로그도 있고, 영상 제작 도구도 있고, 작은 웹서비스와 데스크톱 앱도 있다. 하나씩 만들 때는 그저 당장 필요한 것을 고른다고 생각했는데, 모아 놓으니 반복되는 선택이 꽤 보였다.\u003c/p\u003e","title":"프로젝트를 늘려 보니 남은 기술 스택"},{"content":"올해 초부터 결혼 준비를 시작했다. 준비 기간은 10개월이다. 날짜를 정하고, 예식장과 신혼집을 알아보고, 하나씩 계약을 진행하다 보니 자연스럽게 돈 이야기를 많이 하게 됐다.\n그동안 자산 관리는 주로 먼 미래를 생각하며 해왔다. 당장 쓰지 않을 돈을 어떻게 굴릴지, 월급에서 얼마를 투자할지, 포트폴리오의 변동성을 어느 정도까지 감당할지를 고민했다. 그런데 결혼 준비는 조금 다른 종류의 목표였다. 언제쯤, 어디에, 얼마가 필요한지가 비교적 또렷하다. 막연히 자산을 늘리는 일과는 판단 기준이 달랐다.\n그래서 ISA 적립을 중단하고 결혼 자금을 따로 모으기 시작했다. 국내외 정세와 시장을 보며 자산 구성도 조금 바꿨다. 이 글은 투자 조언이라기보다, 결혼을 준비하는 한 사람의 중간 점검에 가깝다.\n10개월 안에 쓸 돈이 생겼다 가장 먼저 한 일은 결혼과 관련해 쓸 돈을 투자 자산과 분리해서 보는 것이었다. 장기 투자를 위한 ISA 적립은 일단 멈췄다. 10개월 안에 필요한 돈까지 계속 투자 계좌로 넣는 건 지금의 목표와 맞지 않는다고 생각했다.\n월세 보증금은 전월세 대출을 활용하기로 했다. 그 외의 돈은 결혼 자금으로 준비하고 있다. 예식, 신혼여행, 가전·가구처럼 몇 달 안에 지출할 항목을 정리해 보니 생각보다 금액도 크고, 시점도 제각각이었다. 하나의 큰 예산으로만 보면 아직 시간이 남은 것 같다가도, 계약금과 잔금의 날짜를 나열해 두면 마음이 달라진다. 필요한 순간에 주식 시장이 좋지 않다고 해서 지출을 미룰 수는 없기 때문이다.\n결혼 자금은 매달 250만 원씩 모으기 시작했다. 그런데 준비 과정에서 지출이 생각보다 많았다. 다음 달부터는 월 200만 원으로 줄이기로 했다. 목표 금액을 빨리 채우는 것도 좋지만, 준비 기간 내내 생활이 너무 팍팍해지면 오래 유지하기 어렵다. 이 정도가 지금 내가 계속할 수 있는 금액인 것 같다.\n결혼 준비 자금: 매달 200만 원씩 모으는, 10개월 안에 쓸 돈 월세 보증금: 전월세 대출 활용 장기 투자 자금: 당분간 추가 적립을 멈춘 ISA와 기존 투자 자산 숫자는 아직 계속 바뀌고 있다. 다만 이 구분을 해두니 투자 계좌의 등락을 볼 때와 결혼 예산을 확인할 때, 서로 다른 질문을 할 수 있게 됐다. 결혼 자금에는 수익률보다 확실성이 중요하고, 장기 투자 자금에는 시간을 두고 변동성을 견딜 여지가 있다.\n원화 현금 일부는 달러 자산으로 옮겼다 정권이 교체된 뒤, 원화로 보유하던 자산의 약 40~50%를 달러와 미국 초단기국채, 예금으로 옮겼다. 정세의 방향이나 환율을 정확하게 맞히겠다는 판단은 아니다. 다만 국내 상황의 변화가 환율과 자산 가격에 미칠 수 있다는 생각이 들었고, 원화 자산에만 현금을 두는 것보다 통화를 나눠 두는 편이 내 마음에는 더 편했다.\n미국 초단기국채와 예금은 수익률을 크게 기대하는 자산이라기보다, 당분간 기다릴 현금을 둘 곳으로 봤다. 물론 결혼 비용은 원화로 지출해야 하니, 필요한 자금까지 모두 달러로 바꾸지는 않았다. 가까운 시일 안에 쓸 돈은 원화로 확보하고, 그 밖의 현금 일부만 분산하는 쪽을 택했다.\n국제 부채, 유가, 금리처럼 계속 움직이는 변수도 많았다. 미국과 이란의 충돌이 확산되면서 유가가 크게 흔들린 일도 있었다. 이런 요인이 환율과 시장에 어떤 순서로, 얼마나 반영될지까지 알 수는 없다. 그렇다고 뉴스가 나올 때마다 포트폴리오를 바꾸지는 않으려고 한다. 정세가 불안할수록 확신 있는 전망처럼 들리는 이야기도 많아진다. 하지만 내가 할 수 있는 건 미래를 맞히는 일보다, 어떤 상황이 와도 결혼 준비와 일상을 크게 흔들지 않을 구조를 만드는 일에 더 가깝다고 생각한다.\n아쉬움과 안도감은 같이 온다 올해 시장을 보면서 아쉬운 점도 있다. AI 랠리에 제대로 탑승하지 못했다. 관련 종목과 지수가 오르는 모습을 보며 조금 더 일찍, 혹은 조금 더 크게 투자했어야 했나 하는 생각도 들었다.\n그런데 그 아쉬움만으로 포트폴리오를 다시 흔들고 싶지는 않다. 지나간 랠리를 따라 들어가는 것이 지금의 나에게 맞는 선택인지는 별개의 문제이기 때문이다. 결혼이라는 분명한 지출 계획이 생긴 지금은, 놓친 기회보다 남은 돈을 어떻게 관리할지가 더 중요하다.\nBITO의 꾸준한 하락도 다시 생각하게 만든 사건이었다. 내 계좌 기준으로는 약 50% 하락했고, 기대했던 월 분배금도 줄었다. BITO의 분배금은 고정 배당이 아니라 비트코인 선물·스왑 투자에서 발생한 수익 등에 따라 매월 달라질 수 있다. 그래서 높은 분배율만 보고 현금 흐름을 기대했던 판단도 다시 보게 됐다. ProShares도 월별 분배금이 지급되지 않을 수 있고 금액이 변동할 수 있다고 안내한다.\n반대로 SCHD는 AI 랠리에서 소외되는 것 아닌가 싶었던 때가 있었다. 그런데 미국과 이란의 충돌 등으로 시장이 흔들린 시기에도 꾸준히 올라오는 모습을 보며 생각이 조금 달라졌다. Schwab의 성과 정보에 따르면 SCHD의 2026년 7월 기준 연초 대비 총수익률은 24.0%였다. 물론 이 상승을 전쟁이나 특정 뉴스 하나의 결과라고 말할 수는 없다. 둘을 보며 어떤 자산이 더 좋다고 말하려는 것도 아니다. 다만 지금의 나에게는 큰 등락을 견디며 기다리는 것보다, 내가 이해하고 계속 보유할 수 있는 자산이 더 중요하다는 생각이 든다.\n지금 다시 확인한 기준 이번에 자산을 정리하며 몇 가지 기준을 다시 확인했다.\n가까운 시일 안에 쓸 돈은 변동성이 큰 자산에 두지 않는다. 결혼 자금은 올해 말까지 시장 상황과 관계없이 매달 200만 원씩 확보한다. 환율이나 정세를 맞히려 하기보다, 통화와 자산의 쏠림을 줄인다. 투자 비중은 기대 수익률보다 내가 견딜 수 있는 하락폭으로 생각한다. 결혼 예산은 계약이 진행될수록 바뀔 수 있고, 생활비와 이사 비용도 실제로 살아봐야 알 것 같다. 그래서 한 번에 정답을 만들려고 하지는 않는다. 매달 결혼 자금을 모으고, 지출과 남은 기간을 확인하면서 필요하면 금액을 다시 조절하려고 한다.\n돈을 모으는 이유가 조금 더 구체적으로 보인다 예전에도 돈은 미래의 선택지를 늘려준다고 생각했다. 그런데 결혼을 준비하면서 그 말이 조금 더 구체적으로 느껴진다. 결혼식 자체보다도, 그 이후에 둘이 어떤 집에서 어떻게 살고 싶은지, 예상하지 못한 일이 생겼을 때 얼마나 여유 있게 대응할 수 있는지가 더 큰 문제였다.\n그래서 지금의 자산 관리는 공격적으로 불리는 선택과 보수적으로 불리는 선택 중 하나를 고르는 일이 아니다. 정해진 일정과 새로운 생활을 앞두고, 내가 감당할 수 있는 위험의 크기를 다시 정하는 과정에 가깝다.\n아직 결혼 준비는 진행 중이고, 시장도 정세도 계속 바뀔 것이다. 그래도 ISA 적립을 잠시 멈추고 결혼 자금을 따로 모으기로 한 결정, 원화 현금 일부를 분산한 결정은 지금의 내 상황에는 맞는 것 같다.\n나중에 돌아봤을 때 이 시기가 AI 랠리를 놓친 때나 BITO가 크게 빠진 때로만 기억되지는 않았으면 한다. 둘의 생활을 생각하며 돈의 역할을 다시 배운 시기로 남으면 좋겠다.\n","permalink":"https://blog.yoonho.site/2026-wedding-preparation-asset-management/","summary":"결혼 준비 기간이 10개월로 정해지면서 ISA 적립을 멈추고 결혼 자금을 따로 모으기 시작했다. 원화 자산의 40~50%를 달러·미국 초단기국채·예금으로 옮긴 기록, 그리고 BITO와 SCHD를 보며 든 생각을 정리했다.","title":"결혼 준비 10개월, 자산 관리도 바뀌었다"},{"content":"AI로 영상 만들 때, 처음 욕심은 AI 영상 생성 모델(Kling, Seedance, Veo 등)을 이용하여 만들려고 했습니다.\n그런데 생각보다 프롬프트나 원하는 연출을 구성하기가 어렵더라고요. 만약 내가 정말로 시네마틱 영상물 혹은 여러 인물들의 다이나믹한 연출이 필요한게 아니라면 오히려 비용적인 부분이나 시간 대비 결과물이 아쉬운 경우가 많았습니다.\nImages + Vrew 그래서 욕심을 조금 줄여서 AI영상 자체를 만들기 보다 AI로 이미지와 TTS를 만들고 합치는게 저의 원하는 생성물에 훨씬 가까웠습니다. 초기에는 OpenAI Platform에서 이미지를 프롬프트마다 생성하고, Vrew로 이미지 마다 대본에 대한 TTS 및 화면 전환을 구성했습니다. 그러니 훨씬 생산물의 퀄리티가 좋아졌습니다. 물론 이미지의 인물이 움직이거나 하는 연출은 없었지만 이미지의 무빙이나 전환 효과만으로도 이미지를 보는 지루함은 줄어들었습니다.\nAI 자동화 파이프라인 구성 그런데 막상 한 번 생성물을 만들고나니 한땀한땀 손으로 생성하고 수정하는 수고로움이 많았습니다. 그래서 이것도 자동화해보자 하고 아예 AI에게 맞기는 방향으로 파이프라인을 다시 구성했습니다.\n일단 Hermes Agent를 사용해서 파이프라인과 스킬을 구성했습니다. 그리고 OpenAI Platform에서 API를 사용하는 대신 원래 사용하는 chatGPT 구독을 사용해서 codex로 Provider를 설정했습니다. 그리고 TTS는 클로바더빙, 일레븐랩스, 타입캐스트를 고민했는데 API로 쉽게 사용할 수 있는 타입캐스트를 우선 선정했습니다. 월 무료 사용량도 나쁘지 않았고요. 마지막으로 영상을 만드는 도구는 Remotion을 사용했는데 만약 나중에 OpenDesign과의 연계를 생각하면 HyperFrames도 나쁘지 않을 것 같습니다.\n영상물의 전개를 주면 AI가 아래의 순서대로 영상이 만들어 갑니다.\n전개 내용을 바탕으로 대본을 생성한다. 대본에 따라 등장인물에 대한 캐릭터 시트를 생성한다.(이 부분은 사람의 검토가 필요하다) 대본과 등장인물 캐릭터 시트를 참고하여 각 장면을 생성한다.(이 부분은 사람의 검토이 필요하다) 대본을 참고하여 타입캐스트로 TTS를 생성한다. Remotion으로 대본대로 각 장면과 TTS를 조합하고 각 장면마다 이미지 무빙이나 장면 전환을 적용한다. Remotion으로 렌더링한다. Hermes Agent가 이 파이프라인으로 스킬을 자체적으로 구성하고 특히 중간중간 대화하면서 요청한 내용들을 바탕으로 스킬을 개선해 가기 때문에 반복할수록 결과물의 일관성이 좋아졌습니다.\n이후로 Threads나 다양한 스킬과 프롬프트를 참고해 보니 점차적으로 개선할 여지가 많이 보입니다. 차츰 개선되면 개선한 후기도 한번 올려보도록 하겠습니다.\n","permalink":"https://blog.yoonho.site/make-video-with-ai/","summary":"\u003cp\u003eAI로 영상 만들 때, 처음 욕심은 AI 영상 생성 모델(Kling, Seedance, Veo 등)을 이용하여 만들려고 했습니다.\u003c/p\u003e","title":"AI와 함께 비디오를 만들기"},{"content":"글:언젠가 Ghost로 옮기길 바라며…\n2018년에 언젠가 Ghost 블로그로 옮겨 가야지 했었는데 약 7년만에 드디어 그날이 왔다.\n그 당시에는 Ghost가 디자인도 코드 스닙펫도 깔끔하지 않았던 것으로 기억하는데 최근 docusaurus를 보다가 문득 Ghost가 생각나서 봤는데 너무 괜찮았더라.\n일단 글을 작성하고 퍼블리시 하는 과정이 기존에 markdown으로 관리하던 것보다 편하다. 그리고 고스트 시스템 자체적으로 방문자나 메타데이터 관리, 테마 시스템이 잘 구성되어 있다. 그래서 블로그 시스템 코드를 건들 필요가 많이 없었다.\n그리고 예전에는 어딘가 Ghost 인스턴스를 올려놓기 어려웠는데 지금은 맥미니로 항상 서버를 켜두고 있기 때문에 큰 부담이 없었다.\n앞으로는 더 자주 블로그를 쓸 수 있도록 관심 가져봐야겠다.\n그리고 2026년 8월\u0026hellip; 다시 정적페이지로 변경했다. Ghost를 쓰면서 포스트 퍼블리시가 더 쉬울 것이고 서버 관리도 쉬울 것이라고 생각했지만 막상 운영해보니 포스트 퍼블리시 접근성이 그렇게 좋지도 않았고, AI와의 연계도 좋지 않았다.\n그리고 무엇보다 맥미니를 서버로 사용하는데 맥미니의 서버가 가끔 꺼지거나 컨테이너 메모리를 지속적으로 점유하고 있는 문제가 있었다.\nGhost의 다양한 기능을 써보았다면 좋았겠지만 막상 그것도 쉽지 않았고 사용한다면 유료 구독 플랜을 사용하는게 더 Ghost를 잘 활용하는 방법이었겠지만 가끔 블로그를 쓰는 입장에서는 적절한 타협 선에서 정적페이지 생성 블로그를 쓰는게 더 낫다는 판단이 들었다.\n그래서 포스트들을 전부 마이그레이션 했고 다시 여러 후보 Astro, Hugo, Next.js, Gatsby 등을 검토하다가 최소한의 수정으로 적당한 블로그 플랫폼을 사용할 수 있는 Hugo로 우선 적용했다. 블로그가 성장한다면 더 본격적으로 꾸며보겠지만 그럴 일은 오랜 후에나 있을 것이고 지금도 나쁘지 않을 듯\u0026hellip;\n","permalink":"https://blog.yoonho.site/gyeolgug-geunali-wassda/","summary":"언젠가 Ghost로 옮기길 바라며… 개발 블로그를 시작해야지생각하면서 고려했던 블로그 플랫폼이 많이 있었습니다. 1. Medium 2. tumblr 3. Ghost 4. GitHub pages + Jekyll(or Hexo or Hugo or Ghost) 5. 등등등… yoonho\u0026rsquo;s logs Yoonho Ko","title":"결국 그날이 왔다"},{"content":" 🙋‍♂️ 안녕하세요. 저는 고윤호입니다.\n정보보안을 기초로하여 인프라 및 운용 시스템 보안을 개발하고 싶다는 비전을 가지고 있습니다.\n특히, 지난 세대의 서버 운용에서 벗어나 현대의 트렌드에 발맞춘 모던 서버 개발에 관심이 많습니다. 빠른 개발, 안정적인 운영, 지속적이고 유연한 유지관리를 개발 철학으로 생각하고 있습니다.\n🗃 Projects Outsourcing Serverless GraphQL API 기업용 회계 솔루션을 만드는 회사에서 GraphQL API를 만드는 외주를 받아서 진행하였습니다.\n소요기간: 2개월 의뢰비용: ₩ 00,000,000 Pythons Crawler 인터넷 쇼핑몰을 운영하는 회사로부터 의뢰를 받아 인스타그램을 포함한 사이트 세 곳의 크롤러를 제작하여 판매하였습니다.\n소요기간: 건당 4 ~ 5시간 의뢰비용: ₩ 000,000 Toy Projects 버끝업(버튼 하나로 끝나는 업무) M++ 동아리에서 진행한 프로젝트로 각 행정 부처 업무에 관하여 매르로를 제작하여 편의성과 효율성을 도와주는 업무 자동화 프로젝트입니다.\n그 외...\n👨‍🏫 Presentations 클라우드 컨테이너 환경에서 Back-end API 구성하기 AtoZ Amathon 사전 세션 / 29, August 2019\nAWS ECS를 통해 Container 환경에서 Back-end API(REST API와 GraphQL API)를 구성 배포하는 방법을 알아봅시다.\nECS에 EC2 기반의 컨테이너를 배치합니다. ECR을 이용해 커스텀 컨테이너를 배포합니다.\nS3를 이용하여 워드프레스의 이메일 문의 기능 만들어보기 AUSG Hand-on 부스, AWS Univ. Expo / 10, May 2019\n핸즈온에서는 EC2를 사용하여 워드프레스를 실행시키고, RDS를 연동하여 직접 데이터를 저장하는 과정과 마지막으로 S3를 사용하여 정적 파일을 업로드하는 과정을 실습합니다.\n실습에 이용되는 서비스는 프리티어 내에서 진행되며, 마지막 S3 부스에서 생성한 모든 서비스를 삭제하는 실습이 진행될 예정입니다...\nNode.js 서버리스 프레임웍을 사용하여 싱글페이지 포트폴리오 제작하기 AUSG, 2018 F/W 초보자를 위한 AWS 뿌시기 / 19, September 2018\nServerless Framework를 이용하여 AWS Lambda와 API Gateway에 SPA(Single Page Portfolio) 포트폴리오를 배포해봅니다.\nExpress.js를 이용하여 HTML 파일을 서빙하고 API를 구성하여 DynamoDB에 연결합니다.\nAWS Lambda 병렬 처리를 통한 PDF to Image 사용기 AWSKRUG 서버리스 소모임 / 12, July 2018\n회사에서 PDF로 나온 교재를 이미지로 변환해야하는 일이 있었는데요. 시중에 있는 툴은 모두 한 페이지씩 변환하기 때문에 오래걸리더라구요. 한 페이지에 대략 10~15초 정도가 걸렸기 때문에 100 페이지 이상 이루어지는 교재의 경우 권당 15분 이상씩 걸리는 경우가 허다했습니다.\n(10+@)초 + N페이지 = 파일당 변환 시간 파일당 변환시간 + 변환 요청 파일 수 특히 나중에 도입될 변환 서비스에서 너무 과한 시간이 걸릴 것으로 판단해서 병렬처리를 도입하려고 하였습니다. 그런데 PC에서 병렬처리는 한계가 있기 때문에 AWS Lambda를 이용하기로 결정하였습니다.\n💻 Work Experience 비브로스 2020.02.01 ~ NOW Backend Enginner, R\u0026amp;D Team 헬스케어 앱 \"똑닥\"을 개발하는 비브로스에 재직 중입니다.\n백엔드 개발자로서 근무하고 있으며 팀내 레거시 프로젝트를 Typescript 전환 및 인증서버 구축을 진행하고 있습니다.\n비브로스는 JIRA와 Confluence를 이용하여 팀내 프로젝트를 조율하고 있으며, 매일 데일리 스크럼을 진행하고 있습니다.\nAWS를 이용하여 인프라가 운영되고 있습니다.\nTags: AWS, Typescript, OAuth 2.0, Node.js, MongoDB, Swagger, JIRA\nErion Co., Ltd. 2017.11.01 ~ 2019.07.31 CISO \u0026amp; Lead Backend Engineer 스타트업 이리온컴퍼니에서 CISO 및 Lead Backend Engineer로 약 1년 10개월 근무했습니다.\n첫 영입 멤버로서 적은 지분이지만 스톡옵션을 받아 이사로 회사 경영에 일부 참여했으며, 개발팀 PM으로서 개발팀의 스케줄과 제품 퀄리티를 조율했습니다.\nAWS를 이용하여 Serverless GraphQL API와 OAuth 2.0을 구현한 인증 서버를 운용하였고, 그 외에도 사내 소규모 프로젝트에서도 최신 트렌드에 발맞춰 개발 효율을 중점으로 작업했습니다.\nTags: AWS, Typescript, Serverless, GraphQL, OAuth 2.0, Apollo, Node.js, Prisma\n대한민국 공군 2014.06.23 ~ 2016.06.22(만기 전역) 정보보호병 대한민국 공군에 정보보호병 지정 특기를 받아 복무를 마쳤습니다. 부대에서 다양한 정보보호시스템과 서버실과 서버 운영 등을 담당했습니다. 2년동안 공군에서 개최하는 정보보호대회에 참여하였으며, 정보보호 프로그래밍 공모전에서 패스워드 관리 프로그램을 제작하여 수상하였습니다\nTags: Information Security, Security, Server\n🚀 Extracurricular Activities AUSG(2기) 2018.09 ~ AWSKRUG의 소속의 AUSG라는 그룹에서 활동하고 있습니다.\nAWSKRUG(한국사용자모임)는 국내 최대 규모 개발자 커뮤니티 풀로써 다양한 직군의 개발자들이 모여 서로의 기술과 경험을 나누는 모임입니다.\nAUSG는 대학생들이 함께 모여 AWS와 개발 경험을 함께 공유하고 배우며 전파하는 역할을 하고 있습니다.\n2019년 2월에는 일본 도쿄에서 열리는 JAWSDays에 참가했습니다. AWS의 클라우드 컴퓨팅을 이용하여 다양한 세션을 발표했으며 적극적인 참여와 기여를 인정받아 동해 12월에 미국 라스베가스에서 열리는 re:Invent 행사에 참석하게 되었습니다.\nTags: AWS, EC2, ECS, Route53, Lambda, API Gateway\nHUB 2012.03 ~ 2017 HUB는 KUCIS에 속한 백석대학교 정보보호 동아리입니다. KUCIS(대학정보보호동아리연합회)는 KISA 소속의 전국 대학 정보보호 동아리의 연합회입니다. HUB는 백석대에서 유일한 정보보호 동아리며 활발한 활동으로 KUCIS에서 여러번 우수 동아리로 선정 되었습니다.\n저는 2012년 신입생때부터 활동하여 다양한 스터디를 진행하였고, 여러번 해킹대회에 참여했습니다. 또한 동아리 활동을 기반으로 공군에 정보보호병으로 지정특기를 받아 입대하였습니다.\nTags: Security, Programming, KUCIS, KISA, Hacking\nM++ 2015.08 ~ 2016.06.22 부회장(창립 멤버) M++은 대한민국 공군 00부대에서 창립한 프로그래밍 동아리입니다. 프로그래밍에 관심 있는 병사들을 모아 만들었으며 전역하기까지 약 10개월의 기간동안 다양한 스터디 그룹과 프로젝트를 개설하여 진행하였습니다.\n대표 프로젝트: \"Python 기초 프로그래밍\" / \"버끝업(버튼 하나로 끝나는 업무)\" / \"키위 위키(위키백과)\" / \"알파오(오목 AI)\"...\nTags: Programming, Python, Excel, Visual Basic, C/C++, macro\n🪪 Skills Awards and Certificate 📃 실전형 사이버 훈련장(Sercurity-Gym)[4차] / 수료증 한국인터넷진흥원 2017-08-11 certificateOfACourse 📃 안드로이드 앱 취약점 진단 및 분석 2차 / 수료증 한국인터넷진흥원 2017-08-04 certificateOfACourse 🏅 프로그래밍 경진대회 / 은상 백석대학교 정보통신학부 2017-05-31 award 🎫 태권도 / 4단 국기원 2016-07-19 certificate 🏅대학생 STARTUP / App 부분 대상 마이스타일 트렌드페어 2016 2016-11-10 award 🏅우수논문상 (사)한국인터넷방송통신학회 2016-11-10 award 📃 찾아가는 특허정보검색교육 / 수료증 백석대학교 창업보육센터 2014-04-18 certificateOfACourse 🎫 리눅스마스터 / 2급 KAIT(한국정보통신진흥협회) 2013-06-28 certificate 🏅2013 동계 창업캠프 SNU Start-up / 우수팀상 서울대 경력개발센터\u0026amp;기술지주회사 2013-12-28 award 🎫 인성개발지도사 / 2급 인성개발원 2013-12-28 certificate 🎫 해킹보안전문가 / 3급 (사)한국해킹보안협회 2012-12-22 certificate 🏅우수상 백석쿰인성개발원 2012-09-20 award ","permalink":"https://blog.yoonho.site/resume/","summary":"🙋‍♂️ 안녕하세요. 저는 고윤호입니다. 정보보안을 기초로하여 인프라 및 운용 시스템 보안을 개발하고 싶다는 비전을 가지고 있습니다. 특히, 지난 세대의 서버 운용에서 벗어나 현대의 트렌드에 발맞춘 모던 서버 개발에 관심이 많습니다. 빠른 개발, 안정적인 운영, 지속적이고 유연한 유지관리를 개발 철학으로 생각하고","title":"Resume"},{"content":"내가 주식을 시작하게 된 두 가지 이유를 얘기해 보려고 한다.\n시간은 금이다. 아니, 금보다 귀하다. 나보다 똑똑한 사람들에게 맡긴다. 그렇다 하더라도 내가 자본을 늘려야 하는 이유 글을 통해 내가 \u0026ldquo;내게 주어진 가정\u0026quot;을 얼마나 소중하게 생각하는지 알 수 있을 것이다.\n그런데 만약, 내가 가족의 부양을 위해서 \u0026ldquo;부업\u0026quot;으로 많은 시간을 소모한다면 나와 내 가정이 행복할 수 있을까?\n처음 현재 근로 외 소득을 위해서 부업이나 수익 자동화 시스템을 생각했었으나 이러한 시스템은 좋든 싫은 하루 30분이라도 시간을 소비해야 하는 경우가 대다수였다.\n그런데 가만히 생각해 보니 이 방법은 내가 원하는 게 아니었다. 나는 가족들과 더 행복한 시간을 만들기 위해서 소득을 늘리려고 했던 것이지 돈이 급해서 혹은 돈 자체에 목적이 있어서 시작한 게 아니었다.\n그래서 \u0026ldquo;돈이 돈을 번다\u0026quot;라는 말처럼 내가 많은 시간을 쏟지 않더라도 스스로 불어나는 구조를 만들어야겠다고 생각했다. 처음에는 좀 작은 금액이어도 괜찮다. 스노우볼처럼 구르고 구르다 보면 내가 여유를 살 수 있을 정도로 적당한 금액이 들어오기 시작할 테니까\n세상에 거인은 많다 그럼 나는 \u0026ldquo;If I have seen further it is by standing on ye sholders of Giants.\u0026rdquo;\n\u0026ldquo;내가 멀리 볼 수 있었던 것은 거인의 어깨 위에 있었기 때문이다.\u0026rdquo;\n— 아이작 뉴턴 내가 좋아하는 문구다. 뉴턴이 처음 한 말이 아니라고 하는데, 그 말을 뉴턴이 했는지는 내게 중요하지 않다. 어쨌든 뉴턴 같은 위인도 이 말에 공감했다는 것이다.\n나는 짧다면 짧고 길다면 긴 6년의 개발자 커리어를 쌓으면서 늘 생각하는 사실이 있다. 바로 \u0026ldquo;세상에는 나보다 똑똑한 사람이 많다\u0026quot;라는 것이다.\n세상에서 1등이 되는 것, 혹은 그에 준하는 엘리트가 되는 것은 정말 멋진 일이고 자신을 사랑할 수 있는 이유라고 생각한다. 그런데 현실의 나는 그렇지 못할 때가 많다. 내가 속한 작은 조직에서, 혹은 내가 잘 아는 어떤 좁은 분야에서 조금 특출날 뿐이다.\n그래서 나는 나보다 똑똑한 사람의 등에 얻어 탄다. 세상에 잘 만들어진 수많은 개발 라이브러리들이 있듯이, 작은 금액으로 그들의 노력과 기술을 살 수 있듯이, 나는 세상에 있는 거인들을 통해 좀 더 먼 곳을 손쉽게 볼 수 있다. 내가 거인이 되지 않더라도!\n몇 년 전 OpenAI가 ChatGPT를 선보이고 전 세계가 열광했을 때, 나는 이걸로 어떤 재미난 것들을 할 수 있을까 생각하고 있었다. 그런데 어떤 사람들은 OpenAI의 열광을 보고 AI에 투자하기 시작했다.\n만약 내가 AI에 대한 관심이 개발자의 시선이 아니라, 투자자의 시선이었다면 나는 꽤 많은 수익을 얻었을 것이다. 개발자로서 AI를 활용해 무언가를 만드는 건 꽤나 어려운 일이지만, 성장하는 AI 회사에 투자하는 것은 몇 번의 터치만으로 손쉽게 되는 일이다. 그렇다면 투자를 먼저 해두고 내가 하고 싶은 걸 해도 됐을텐데 말이다.\n왜 주식이었을까 세상에 주식만큼 손쉬운 투자는 없는 것 같다. 오죽하면 주식시장을 \u0026ldquo;자본주의의 꽃\u0026quot;이라고 부를까? 조금 더 일찍 깨달았다면, 조금 더 관심을 가졌었다면, 조금 더 두려워하지 말았다면 오늘의 나는 지난 세월의 나보다 10% 정도는 더 부유한 나였을지도 모른다.\n후회는 언제해도 늦었다. 하지만 시작은 지금이 가장 빠르다.\n","permalink":"https://blog.yoonho.site/why-im-invested-in-stocks/","summary":"내가 주식을 시작하게 된 두 가지 이유를 얘기해 보려고 한다. 시간은 금이다. 아니, 금보다 귀하다. 나보다 똑똑한 사람들에게 맡긴다. 그렇다 하더라도 내가 자본을 늘려야 하는 이유 글을 통해 내가 \u0026ldquo;내게 주어진 가정\u0026quot;을 얼마나 소중하게 생각하는지 알 수 있을 것이다. 그런데 만약, 내가 가족의 부양을 위해서","title":"주식에 관심을 갖게 된 이유"},{"content":" 저의 생각과 경험을 보러 와주셔서 감사합니다.\n저의 작은 경험과 얕은 생각이 여러분들에게 도움이 되시기를 바랍니다.\n기존에 운영하던 블로그는 여기서 확인할 수 있습니다.\n저에 대한 간단한 이력은 여기서 확인하실 수 있습니다.\n👉🏻 RESUME👨🏻‍💻 이 노트 저장소는 저의 PKM 중 일부 함께 공유하고 싶은 내용들이 올라오는 공간입니다. 그 중 저의 관심사들을 나누어 카테고리를 분류하였습니다.\nInvestment Note Development Note(아직 개설하지 않았습니다) Life Note(아직 개설하지 않았습니다) 🧰 Tech Stack 🧰 ▶️ Languages ◀️ ▶️ Platforms \u0026amp; Databases \u0026amp; Frameworks ◀️ ▶️ Async Tools ◀️ ▶️ Sync Tools ◀️ ▶️ Others ◀️ ","permalink":"https://blog.yoonho.site/about/","summary":"저의 생각과 경험을 보러 와주셔서 감사합니다. 저의 작은 경험과 얕은 생각이 여러분들에게 도움이 되시기를 바랍니다. 기존에 운영하던 블로그는 여기서 확인할 수 있습니다. 저에 대한 간단한 이력은 여기서 확인하실 수 있습니다. 👉🏻 RESUME 👨🏻‍💻 이 노트 저장소는 저의 PKM 중 일부 함께 공유하고 싶은 내용들이","title":"About me"},{"content":"도어대시 전량 매도 도어대시 전량 매도 했습니다.\n도어대시 평균 매입가 $137.53에 사서 $145에 4.91% 수익 보고 익절했습니다.\n아마 21년 연말 혹은 22년 연초 쯤 가격이 매력적인 부분으로 내려오니 샀었나 봅니다. 그 당시에는 제가 아니라 제 동생이 제 주식을 관리했었습니다.\n아무튼 10월 11일 오랜 기간 수익률이 마이너스를 유지하다가 드디어 익절가로 올라왔길레 뒤도 안돌아보고 팔아버렸습니다.\n도어대시의 경영 개선이나 순이익 개선에 대해서 최근 확인하다가 다른 투자처를 찾는게 더 이득일 것 같아 2~3년 만에 겨우 5% 수익률로 전량 매도했습니다.\n만나서 반가웠고 다시는 보지 말자 👋🏻\nQLD 전량 매도 QLD는 그동안 본 손실들을 일부 매울 수 있었던 희망이자 효자 ETF였습니다.\n오늘 날짜로 96.68% 수익률에 전량 매도했습니다.\nQLD 만으로는 그동안 본 모든 손실을 다 매울 수는 없지만 그래도 투자를 계속할 수 있었던 버팀목이 됐던 것 같습니다.\n그렇다고 전량 매도가 수익 실현 때문인가 하면 그렇지는 않습니다. 좀더 근본적인 이유는 오히려 손해 때문이었는데요. 보유 주식 매도(24년 6월)에서 언급한 노답 3형제의 손해가 워낙 큰 상황이었는데 해외 주식은 해마다 손익통산이 되기 때문에 올해 매도를 해야 세금 문제가 없을 것으로 판단했기 때문입니다.\n블로그의 다른 글 보유 주식 매도(24년 6월)노답 3형제 정리 더 가지고 있어도 답이 없었을 노답 3형제 레모네이드: 61.2% SEA(ADR): 59.42% 텔러닥 헬스: 85.41% 수익률 뿐만 아니라 실현손익 자금 자체가 너무 큰 손해를 봤는데 더 이상 회생도 불가능할 것 같아서 5월 20일에 전량 매도했다. 효자 QLD 일부 매도 반면 QLD는 88.41% 2024. 06. 25#investment#portfolio ↗ 이번에 매도한 QLD 덕분에 올해 손익통산 + 비과세 250만원까지 꽉 채워서 일단 정리가 된 상황이고요. QLD를 매도한 금액은 현금화해서 연금계좌로 옮겨 TIGER 나스닥100이나 TIGER 나스닥100레버리지(합성) 상품으로 같은 금액만큼 구매하려고 합니다.\n개인적으로는 미장이 전체적으로 특히 기술주 중심으로 고평가되어 있다고 생각하고 있습니다만 그것과 별개로 그동안 유지해온 주식이니 같은 금액만큼 QLD를 매수해두고 한번씩 폭락 시기가 오면 줍줍하려고 합니다.\n미래에셋미국배당프리미엄증권투자신탁(주식)(UH)종류A-e 지금은 이름이 바뀌어서 커버드콜 상품으로 적혀있는데, 이건 짧은 기간에 충분히 자기 역할을 잘 한 것 같고 커버드콜 펀드 비중을 낮추기 위해서 전량 매도했습니다.\n펀드 상품이라 매도까지 시간이 걸리는데 그런 부분이 계속 마음에 걸리기도 했고 기왕 이것저것 정리하는 김에 같이 처분했습니다.\n2024년 10월 14일 포트폴리오 현금성 자산(27.53%) TIGER CD금리투자KIS(합성) 1.24% 현금 26.29% 채권(9.59%) BND 9.59% KODEX TDF2050액티브 TIGER 미국투자등급회사채액티브 TIGER 글로벌멀티에셋TIF액티브 성장형 주식(31.56%) DASH 10.13% → 현금화 QLD 9.65% → 연금계좌로 이동 PYPL 8.14% ABNB 3.64% 배당형 주식(15.66%) TIGER 미국배당다우존스 8.19% 미래에셋미국배당프리미엄증권투자신탁(주식)(UH)종류A-e 7.47% 모햇-매월드림모햇PLUS 15.25% ","permalink":"https://blog.yoonho.site/rebalancing-portfolio-2024-10/","summary":"도어대시 전량 매도 도어대시 전량 매도 했습니다. 도어대시 평균 매입가 $137.53에 사서 $145에 4.91% 수익 보고 익절했습니다. 아마 21년 연말 혹은 22년 연초 쯤 가격이 매력적인 부분으로 내려오니 샀었나 봅니다. 그 당시에는 제가 아니라 제 동생이 제 주식을 관리했었습니다. 아무튼 10월 11일 오랜","title":"도어대시 익절 및 QLD 전량 매도"},{"content":"빠르지 않았다 재작년이었나? 이전 회사 동료분들끼리 같이 모이는 날이 있었다. 그때 누나가 한 명 있었는데 연금 꼭 들으라고 그래야 연말정산에 공제받는다고 신신당부하던 날이 있었다.\n그때는 한 귀로 듣고 한 귀로 흘렸었다. 세액공제받는 것도 좋지만 당장 저축하고 결혼 자금 모아두고 할 돈도 넉넉하지 않은 처지에 연금 때까지 묵힐 돈이 어디 있나 생각했다.\n게다가 25년 이상 지난 이후의 일을 벌써 신경 써야 하나 하는 안일함도 있었다.\n그런데 얼마 전 문득 퇴직연금을 리밸런싱 하다가 문득 공제받는 금액이 궁금했다. 그래서 이리저리 찾아보다가 자산 목표에서 연금저축을 빼놓을 수 없다는 걸 알았다.\n연금 수령 가능한 만 55세까지 앞으로 나에게 무슨 일이 벌어질까?\n24년 동안 그 동안 아마 결혼도 하고, 집도 사고, 아이도 낳을 거다.\n결혼하는데 5천 이상은 거뜬히 들어가겠지. 혼수 장만하고, 집 전세금/보증금도 들어갈 테고, 차도 필요할지 모른다. 아이들을 키우는 동안 학비, 교육비, 옷, 식비, 생활비 등등.. 세상에 벌써 아찔하다.\n그런데 그 이후에는? 내가 만 55세가 될 때면 아이들은 대학교를 들어가고, 부모님과 처가 장인 장모님 나이도 어느새 여든을 훌쩍 넘기실 테다. 온갖 병원비 다 들어갈 텐데 나의 직장이나 급여는 안정적일까? 그 후로도 내 가족을 부양할 수 있을까?\n그렇게 생각하니 지금 가지고 있는 수준으로는 어림도 없었다. 미리 준비해야 한다. 현재가 아니라 미래를 봐야 한다.\n결혼식 2024년 평균을 확인하려 이 기사를 참고했다.\n예식장(교회에서 식을 한다면 좀 저렴할 거다) 990만원 스드메 479만원 혼수 2,615만원 신혼집 2억 4,176만원 신혼여행 744만원 예단, 예물 합 1,100만원 대충 합이 3억 104만 원 정도 들어간다. 신혼집 제외하면 약 6천만 원 정도 들어간다. 신혼집은 월세 보증금 혹은 전세 대출받는다고 생각해야겠다.\n살림은 시작도 안 했는데 돈이 줄줄 샌다. 이러니 다들 포기하고 사나 보다 싶다. 우리 부모님은 없는 살림에 단칸방에서 시작하셨다는데 정말 존경스럽다.\n아무튼 아내 될 사람과 현실적으로 맞춰 나간다고 생각하면 집 빼고 4천이면 되지 않을까?\n결혼했다 치고 이것도 2024년 평균을 확인하려 기사를 참고했다.\n아이도 낳겠지 대한민국 출산율 기여를 위해 둘 낳는다고 생각하면 월평균 예상 양육비는 280만 원이다. 다른 기사를 보니 2021년 자료에 자녀 1인당 월 72만원 정도 들어간다는데 그새 많이도 올랐다.\n양육비 280만 원으로 셈 치고 생활비, 대출 이자, 교통/유류비 나가면 400만 원 이상은 거뜬히 나가겠다. 이래서 언제 저축할 수 있겠나?\n할 수 있는 건 다 해야 한다 탈세를 할 수는 없으니 공제받고 혜택받을 수 있는 건 최대한 준비해야 한다. 특히 아직 다가오지 않은 지금 모든 걸 준비하고 있어야 한다. 일 년 일 년이 소중한 시점이다. 좀 더 미리 하면 어땠을까 하는 후회 같은 건 사치다.\n매월 ISA 167만 원(연 2,000만 원) 매월 연금저축계좌 50만 원(연 600만 원) 매월 IRP 25만 원(연 300만 원) 가능하다면 연금저축계좌(비공제)에 최대 1,500만 원까지 매월 최소 242만 원, 최대 367만 원씩 저축해야 한다. 그럼 연 2,900만 원씩 저축할 수 있고, 수익/배당을 제외하더라도 세액공제도 118만 원까지 받을 수 있다.\nISA 만기 후 연금저축계좌로 이전하면 10%(최대 300만 원)까지 세액공제를 받을 수 있다. 그럼 3,000만 원까지 옮길 수 있으니 나머지는 연금저축계좌에 넣어서 원래 해마다 1,800만 원까지 밖에 납입하지 못하던 불편함을 해소할 수 있다.\n내년엔 ISA 계좌 한도가 두 배 더 오르도록 추진한다고 한다. 이것도 미리 생각해 보자.\n","permalink":"https://blog.yoonho.site/for-24-years/","summary":"빠르지 않았다 재작년이었나? 이전 회사 동료분들끼리 같이 모이는 날이 있었다. 그때 누나가 한 명 있었는데 연금 꼭 들으라고 그래야 연말정산에 공제받는다고 신신당부하던 날이 있었다. 그때는 한 귀로 듣고 한 귀로 흘렸었다. 세액공제받는 것도 좋지만 당장 저축하고 결혼 자금 모아두고 할 돈도 넉넉하지 않은 처지에 연금","title":"24년 동안"},{"content":"기준이 무엇인가 나는 주식 투자에 대해서 모르는게 아직 많다. 그러니까 주린이라는 얘기다.\n그런 내가 주식 종목을 선택한다면 무슨 주식을 살지 어떻게 고를 수 있을까?\n인터넷/지인을 통해 들은 요즘 대세인 \u0026ldquo;이것\u0026rdquo; 을 산다. 수익률로 정렬하여 수익률이 높은 \u0026ldquo;이것\u0026rdquo; 을 산다. 뭔가 이름이 맘에 드니까, 이 기업은 자주 들어봤으니까 \u0026ldquo;이것\u0026rdquo; 을 산다. 요즘 이 종목이 저평가 되어 있다고 하니까 \u0026ldquo;이것\u0026rdquo; 을 산다. 재무제표가 좋으니, PER 가 어떠니 \u0026ldquo;이것\u0026rdquo; 을 산다. 배당률이 좋다고 하니 \u0026ldquo;이것\u0026rdquo; 을 산다. 기타 등등 주식 종목을 고른다는 것에 어떤 주관으로 사람마다 다 다를 것이다.\n그렇게 고른 주식이 오르고 내리고 출렁거릴 때, 과연 나는 그 주관을 유지할 수 있을 것인가?\n애초에 매수의 근거가 된 \u0026ldquo;내 주관\u0026rdquo; 은 변하지 않고 지속 가능한 \u0026ldquo;기준\u0026rdquo; 이 되는가?\n그래서 나는 \u0026ldquo;적절한 기준\u0026rdquo; 을 찾아봤다. 왜냐면 \u0026ldquo;내 주관\u0026rdquo; 은 시간에 따라 시장에 따라 변할 수 있지만 \u0026ldquo;기준\u0026rdquo; 은 항상 어느 때나 똑같을 것이기 때문이다.\nETF 는 기준에 묶인 상품이 많다 그러다가 개별 종목이 아니라 ETF 에 눈으르 뒀다. 대표적인 ETF 상품들을 보니 보통 상품을 만들기 위해 어떤 분류법이 존재했다.\n💡[예시]\u0026ldquo;TIGER S\u0026amp;P500\u0026rdquo; 은 \u0026ldquo;TIGER\u0026rdquo;(미래에셋자산운용) 에서 운용하는 \u0026ldquo;S\u0026amp;P500\u0026rdquo; 지수를 추종하는 ETF 상품이다.\u0026ldquo;KODEX 인도 Nifty50\u0026rdquo; 은 \u0026ldquo;KODEX\u0026rdquo;(삼성자산운용) 에서 운용하는 인도의 Nifty 에 상장된 50 개 기업에 투자하는 ETF 상품이다.\n그런데 이런 ETF 상품들도 알아보니 수 많은 종류를 가지고 있었다. 그 중에 내가 생각한 \u0026quot; 기준 \u0026quot; 을 가진 ETF 들은 대표적으로 아래와 같았다.\nS\u0026amp;P500: 미국의 스탠더드 앤드 푸어사가 기업규모·유동성·산업대표성을 감안하여 선정한 보통주 500 종목을 대상으로 작성해 발표하는 주가지수 - 네이버페이 증권에서 발췌 QQQ: 이 펀드는 일반적으로 나스닥 -100 지수의 부품증권의 가격과 수익성과에 상응하는 투자 성과를 제공하고자 합니다. - 네이버페이 증권에서 발췌 SCHD: 이 펀드는 Dow Jones U.S. Dividend 100 Index 의 총 수익을 추적하려고합니다. 이 지수는 재무 비율을 기반으로 동료와 비교할 때 기본 강점으로 선택된 지속적으로 지불하는 배당금을 기록한 미국 배당 수익률이 높은 미국 회사의 주식 성과를 측정하도록 설계되었습니다. - 네이버페이 증권에서 발췌 그 외 여러 상품들이 있었지만 내가 본 상품 중에 가장 까다롭게 선정됐다고 생각이 드는 상품이 바로 \u0026ldquo;SCHD\u0026rdquo; 였다.\n문턱이 몇 개야 SCHD 에 포함되기 위해서는 아래의 조건을 만족하는 기업이어야 한다. 참고\n엄밀하게 말하자면 SCHD 는 Dow Jones Dividend 100 지수를 따르고 있기 때문에 Dow Jones Dividend 100 의 선정 기준이다.\n최소 10 년 연속 배당지급 종목 포함 연환산배당 (IAD) 수익률에 따른 순서 매기기 해당 수익률이 적격한 중간종목의 IAD 수익률보다 낮은 종목 배제 총부채 대비 잉여현금흐름 (FCF) 자기자본수익률 (ROE) IAD 수익률 5 년 배당성장률로 구성된 동등가중종합점수 기준 상위 100 개 종목 선정 (국제 버전) 3 년 가격 변동성이 가장 높은 종목 중 하위 절반 배제 유동 시가총액 방식 (가중치 상한 적용) 으로 분기별 구성종목 가중치 부여 이런 다양한 조건을 모두 충족하는 기업이 몇 개나 될까? 그렇기 때문에 SCHD 포트폴리오에 포함되어 있는 기업들은 우수하고 우수성을 유지하는 기업이라고 판단할 수 있다.\n이런 평가를 받는 기업은 어느 때 들어가도 적당하다고 생각한다.\n기피하는 ETF 혹은 상품 동일한 이유로 종목 선정에서 배제하는 상품들이 있다.\n개별 종목은 구매하지 않는다. 개별 종목은 확실하게 회사의 (잠재 혹은 현재) 성장성과 이익률이 높더라도 개인 투자자인 내가 전업도 아닌데 꾸준히 모니터링하기 어렵다고 생각한다. 그러니 그런 일은 더 잘하는 전문가들에게 맡기는 게 좋다고 생각한다.(나의 건강한 멘탈과 현생을 위해서라도)\nETF여도 지수가 아닌 어떤 기업을 추구하는 상품은 피한다. 몇몇 ETF는 특정 종목과 몇몇 곁가지 종목들로 구성하는 상품이 있다.\n예를 들면,\nRISE 글로벌리얼티인컴 ACE 엔비디아채권혼합블룸버그 TIGER 테슬라채권혼합 Fn 이런 상품은 목적이 있다.\n내가 원하는 어떤 기업의 주식을 직접 구매할 수 없는 계좌거나 퇴직연금 위험자산 투자제한을 우회하거나 그 외 등등 아무튼 \u0026ldquo;어떤 기업\u0026quot;에 투자하고 싶은데 ETF로 구성된 상품을 사고자 할 때다.\n그런데 \u0026ldquo;어떤 기업\u0026quot;에 투자한다는 의미 자체가 위험하다고 생각한다. \u0026ldquo;어떤 기업\u0026quot;에 투자한다는 것은 기업 자체가 기준이 된다. 시장의 상황이 바뀌고, 기업의 전망이 바뀌어도 해당 기업이 기준이기 때문에 오르고 내리는 주가의 변동 상황에서 고민이 깊어지게 된다.\n결론 내가 왜 SCHD를 매수했는지를 설명하면서 어떤 종목은 사지 않는지 나의 생각을 풀어봤다. 투자하는 개인마다 생각이 다양하고 본인만의 추구하는 투자 성향이 있을 거다. 각자의 투자는 각자의 책임에 있다.\n그리고 급성장하는 기업을 찾아서 투자하는 것보다 더 중요한 것은 없는지, 그리고 나는 \u0026lsquo;나의 투자 방식\u0026rsquo;에 걸맞은 자세와 마음을 가지고 있는 사람인지 되돌아보자.\n","permalink":"https://blog.yoonho.site/buying-schd-reasons/","summary":"기준이 무엇인가 나는 주식 투자에 대해서 모르는게 아직 많다. 그러니까 주린이라는 얘기다. 그런 내가 주식 종목을 선택한다면 무슨 주식을 살지 어떻게 고를 수 있을까? 인터넷/지인을 통해 들은 요즘 대세인 \u0026ldquo;이것\u0026rdquo; 을 산다. 수익률로 정렬하여 수익률이 높은 \u0026ldquo;이것\u0026rdquo; 을 산다. 뭔가 이름이 맘에 드니까, 이 기업은 자주","title":"미국배당다우존스를 매수한 이유"},{"content":"현재 포트폴리오 2024년 8월 26일 현재 나의 포트폴리오 구성을 풀어보겠다.\n현금성 자산(27.53%) TIGER CD금리투자KIS(합성) 1.24% 현금 26.29% 채권(9.59%) BND 9.59% 성장형 주식(31.56%) DASH 10.13% QLD 9.65% PYPL 8.14% ABNB 3.64% 배당형 주식(15.66%) TIGER 미국배당다우존스 8.19% 미래에셋미국배당프리미엄증권투자신탁(주식)(UH)종류A-e 7.47% 모햇-매월드림모햇PLUS 15.25% 변경할 포트폴리오 이 구성 중에서 가능하다면 올해 안에 점차적으로 포트폴리오 비율을 변경할 예정이다.\n현금성 자산(27.53% → 10%): 일부는 상황에 따라 금 혹은 금 관련된 것을 구매할 수 도 있다. 채권(10%) 성장형 주식(31.56% → 20%) DASH 10.13% → 0% QLD 9.65% → 20%: 본래 레버리지 투자는 나의 투자 성향과 맞지 않으나 이미 투자가 되어있고 결국 잠재적으로 오를 것을 감안하여 투자하기 때문에 변동성을 감수할 수 있다면 20% 정도는 계속 적립식 매수할 수 있을 것 같다. 혹은 현재 10%를 그대로 두고 QQQ를 10% 적립식 매수할 수도 있다. PYPL 8.14% → 0% ABNB 3.64% → 0% 배당형 주식(15.66% → 45%) TIGER 미국배당다우존스 8.19% 미래에셋미국배당프리미엄증권투자신탁(주식)(UH)종류A-e 7.47% 모햇-매월드림모햇PLUS 15.25% 이 중 모햇은 일정 금액을 예치해두고 매월 이자가 지급되는 상품이다. 따라서 예금형태의 상품이라고 할 수 있는데 이 상품에 대해서는 다른 포스트에서 다뤄보겠다.\n정리 아무튼 올해 목표는 아래와 같다.\n성장형 주식의 비중을 낮추고 점차 배당형 주식으로 옮겨간다. 특히 개별 종목 주식은 ETF로 옮겨갈 예정이다. 자산 분배의 목적과 변동성에 대한 상쇄 효과를 위해서 채권과 금 혹은 현금을 일부 보유한다. 왜 배당형 주식의 비중을 높여가고 ETF를 선호하는지 등 올해 목표에 대한 이유는 다른 포스트에서 다뤄보겠다.\n","permalink":"https://blog.yoonho.site/2024-aug-portfolio/","summary":"현재 포트폴리오 2024년 8월 26일 현재 나의 포트폴리오 구성을 풀어보겠다. 현금성 자산( 27.53% ) TIGER CD금리투자KIS(합성) 1.24% 현금 26.29% 채권( 9.59% ) BND 9.59% 성장형 주식( 31.56% ) DASH 10.13% QLD 9.65% PYPL 8.14% ABNB","title":"2024년 8월 포트폴리오"},{"content":"잠깐 내 이야기를 하자면 나중에 다른 포스트에서도 다루겠지만 내가 가지고 있는 자본을 늘려야겠다고 생각하게 된 이유가 있었다.\n나는 경기도에서 서울로 오랫동안 출퇴근을 하고 있는데 2개의 회사를 다니는 동안 4개의 근무지가 있었고 근무지마다 짧게는 1시간 30분에서 길게는 1시간 50분의 편도 출퇴근 시간이 소요된다.\n따라서 왕복으로 셈하면 대략 3시간에서 3시간 반 정도 소요가 되는데 20대에는 그럭저럭 다닐만했지만 나이가 들수록, 출퇴근을 오래 할수록 힘들었다.\n그래서 자취를 여러 번 고려해 봤지만 매번 금전적인 이유 등으로 살포시 다시 접어두곤 했었는데 이번에 장래에 필요한 금전 계획을 다시 세우면서 왜 지금 저축 기간을 늘려야 하는지 생각을 정리하게 되어서 그 내용을 공유해 보고자 한다.\n내 인생의 우선순위는 무엇인가? 사람마다 자기 인생에 중요한 우선순위가 다양하겠지만 나의 경우 금전은 굉장히 낮은 순위에 있다.\n신앙/기독교적 가치관 가정 자아실현 금전 우선순위에 따라서 삶의 목적, 원동력에 얼마나 영향을 줄 수 있는지, 인생을 얼마나 행복하게 가꿔갈 수 있는지 결정된다고 생각한다.\n그런 의미에서 나의 상위 우선순위는 하위 우선순위의 원동력이 되고, 하위 우선순위는 상위 우선순위의 수단이 된다.(상관관계가 없을 수도 있겠지만 나의 경우 어렴풋이 그렇다고 생각한다.)\n이 중 첫 번째 \u0026ldquo;신앙\u0026quot;은 내가 부유하고 빈곤하고에 따라 신앙에 영향을 미치지 않는다. 실제로 영향을 미치지 않아야 하는 것에 나의 생각과 마음에 따라 달라지는 것뿐이다.\n하지만 부유하면 드리고, 섬기기에 더 유익하므로 많이 드릴 수 있는 환경이 되는 것은 감사한 것이다.\n이 포스트에서 얘기하고자 하는 것은 두 번째 \u0026ldquo;가정\u0026quot;이다.\n나는 현재 결혼적령기이고, 아버지는 곧 은퇴가 가까우시고, 동생은 아직 취업 준비 중이다. 하나씩 자세하게 이야기를 풀어보겠다.\n앞으로 내 가정을 지키기 위해서는 현재 나는 결혼적령기의 나이대이다. 지금(2024년) 30대 초반의 나이이고, 아직 교제 중인 사람은 없지만 결혼하여 가정을 가꿀 의사를 가지고 있다.\n결혼을 하기 전에도, 결혼을 할 때도, 결혼을 한 후에도 잠재적으로 소비되는 비용은 적어도 연인/배우자와 충분히 합의가 되어 절약하더라도 모으기에 쉽지 않은 게 현실이다. 결혼만 해도 예식비, 주택, 차에 비용이 들고 결혼 후에도 월세/이자, 유류비/유지비, 생활비가 꾸준히 들어갈 것을 예상할 수 있다.\n현재 부모님께 매달 생활비를 드리고 있지만 부모님께서 모을 수 있을 만큼 여유있지 않고, 아버지가 은퇴하시더라도 퇴직금은 없다.\n동생은 취직 준비한지 2년정도 됐지만 올해 취직이 된다고 하더라도 안정되고 부모님께 동생이 용돈을 드릴 수 있다고 하더라도 나와 동생이 결혼한다면 그것도 쉽지 않을 수 있다.\n두 부모님 모두 워낙 건강 관리를 열심히 하셨기 때문에 당장 어딘가 아프신 곳이 없기 때문에 큰 비용이 들어갈 일이 없고, 은퇴 이후에도 일을 찾아 하시겠지만 내 금융소득이 계속 증가한다는 보장도 하기 어려울 수 있다.\n이렇게 생각해보니 지금 금융자산을 가지고 안심할 수 있는 단계가 아니라고 생각했다. 앞으로 내가 10년 꾸준히 소득이 생긴다고 해도 앞으로 부모님과 배우자 부모님의 부양과 아내와 자녀들을 부양하려면 현재 소득 이외의 추가 소득이 지속적으로 발생해야 한다고 생각했다.\n소득과 자산이 행복과 동일하지 않겠지만 내가 가지고 있는 행복을 지키기 위해서, 부족함 없는 환경을 유지하기 위해서 할 수 있는 것들은 충분히 해야 한다고 생각했다.\n글에서 금액이나 계획을 일일이 얘기하지 않았지만 앞으로 내가 지속해서 자산이 늘어나고 양가 부모님을 부양하기 위한 생활비 정도는 근로 소득 외에 부가적인 소득이 있어야 한다고 판단했다. 그래야 내 근로 소득만으로 내 가족들을 위해서 온전히 쓸 수 있을 것이기 때문이다.\n쓰려던 내용이 있었는데 짧게 짧게 쓰려던 원래 목표와 다르게 글이 길어지는 것 같아서 다른 포스트에서 주식 투자. 그 중에서 특히 배당 주식에 관심을 갖게 됐는지 작성해보겠다.\n","permalink":"https://blog.yoonho.site/more-capital-needed/","summary":"잠깐 내 이야기를 하자면 나중에 다른 포스트에서도 다루겠지만 내가 가지고 있는 자본을 늘려야겠다고 생각하게 된 이유가 있었다. 나는 경기도에서 서울로 오랫동안 출퇴근을 하고 있는데 2개의 회사를 다니는 동안 4개의 근무지가 있었고 근무지마다 짧게는 1시간 30분에서 길게는 1시간 50분의 편도 출퇴근 시간이 소요된다.","title":"내가 자본을 늘려야 하는 이유"},{"content":"개요 금리 인하 시기에 맞춰서 채권 구매를 고려하게 되었다. 채권과 채권 ETF를 찾아보게 되었다. BND에 10% 정도 구매함 채권이 아니라 채권 ETF를 선택한 이유 채권은 일정 기간동안 비용이 묶이게 된다. 따라서 거래가 자유로운 채권 ETF를 고려하게 되었다. 채권 ETF 종류 국내 주식의 경우 ACE, KODEX, SOL, RISE에서 만든 미국국채30년 같은 장기채 ETF가 있다. 그러나 장기채의 경우 변동성이 심하기 때문에 미국 채권 ETF를 직접 찾아봄.\nTLT, LQD, BND 세가지 미국 상장 채권 ETF를 고려하게 되었다.\nTLT: 미국 장기 국채 ETF LQD: 미국 투자등급 회사채 ETF BND: 미국 장기 국채 + 미국 투자등급 회사채 ETF BND을 구매한 이유 TLT는 변동성이 크고 BND는 지속적인 수익률을 가지고 있으며 가장 큰 자산 규모를 가지고 있다.\n고려할 점 달러 약세가 시작되면 낮아지는 달러로 인해 채권 수익률이 높아져도 손해일 수 있다. 그럼 헤지 상품을 사는게 나았을까? 🤔 ","permalink":"https://blog.yoonho.site/buying-bnd-etf/","summary":"개요 금리 인하 시기에 맞춰서 채권 구매를 고려하게 되었다. 채권과 채권 ETF를 찾아보게 되었다. BND에 10% 정도 구매함 채권이 아니라 채권 ETF를 선택한 이유 채권은 일정 기간동안 비용이 묶이게 된다. 따라서 거래가 자유로운 채권 ETF를 고려하게 되었다. 채권 ETF 종류 국내 주식의 경우 ACE,","title":"BND 구매"},{"content":"보유 주식 매도(24년 6월)에서 얘기한 것처럼 QLD 30%를 추가 매도했다.\n지난 6월 수익률보다 낮은 77.94%에 매도했지만 일단 마음은 안심이다.\n주식을 배울수록 레버리지 상품에 대한 명암을 알게 됐는데 지금은 QLD 비중을 낮추는게 맞다고 생각한다.\n남은 40%는 어떻게 할지 생각해 봐야겠다.\n","permalink":"https://blog.yoonho.site/rebalancing-portfolio-2024-7/","summary":"보유 주식 매도(24년 6월) 에서 얘기한 것처럼 QLD 30%를 추가 매도했다. 지난 6월 수익률보다 낮은 77.94%에 매도했지만 일단 마음은 안심이다. 주식을 배울수록 레버리지 상품에 대한 명암을 알게 됐는데 지금은 QLD 비중을 낮추는게 맞다고 생각한다. 남은 40%는 어떻게 할지 생각해 봐야겠다.","title":"QQQ(QLD) 추가 매도(24년 7월)"},{"content":"노답 3형제 정리 더 가지고 있어도 답이 없었을 노답 3형제\n레모네이드: -61.2% SEA(ADR): -59.42% 텔러닥 헬스: -85.41% 수익률 뿐만 아니라 실현손익 자금 자체가 너무 큰 손해를 봤는데 더 이상 회생도 불가능할 것 같아서 5월 20일에 전량 매도했다.\n효자 QLD 일부 매도 반면 QLD는 88.41% 수익률을 기록하는 중이었는데 곧 금리 인하가 할 것이라는 전망과 시장 변동성을 우려하여 현금화하였다.(왜 QLD는 더 사지 않았니\u0026hellip;)\n전량 매도한 것은 아니고 30% 씩 두 달에 걸쳐 2회 매도하고 현금화한 금액은 일부 다른 투자처에 옮기려고 한다.\n","permalink":"https://blog.yoonho.site/rebalancing-portfolio-2024-6/","summary":"노답 3형제 정리 더 가지고 있어도 답이 없었을 노답 3형제 레모네이드: 61.2% SEA(ADR): 59.42% 텔러닥 헬스: 85.41% 수익률 뿐만 아니라 실현손익 자금 자체가 너무 큰 손해를 봤는데 더 이상 회생도 불가능할 것 같아서 5월 20일에 전량 매도했다. 효자 QLD 일부 매도 반면 QLD는 88.41%","title":"보유 주식 매도(24년 6월)"},{"content":"정확히 기억은 안나지만 Mozilla Servo가 릴리즈 되었으니 아마도 2016이 맞을거 같다. 그때는 한창 대한민국의 자랑스러운 공군 병장으로서 당당히 전날 야간 근무를 마치고 취침 후 사지방에 있었을 때였다(혹은 주말이어서 비번이었건?). 계기는 모르겠지만 어떤 이유로 Mozilla에서 Servo라는 웹 브라우저 엔진을 새로 개발하였고 이는 Rust라는 Mozilla에서 만든 새로운 언어로 개발 됐다는 것을 알게되었다. 어째서였을까? 이건 마치 운명같은 만남이었을까? 나는 Rust 컨셉을 보고는 그대로 이 언어에 매료되었다.\n그 뒤로 Rust 언어에 대해서 튜토리얼과 문서를 보면서 학습은 했지만 우리나라에서 할만한 프로젝트도 없었고 그 이후로 Node.js를 접하면서 이쪽으로 개발만 진행하다 보니 Rust는 내 마음 속 한켠에 있는 짝사랑 같은 존재였달까?\n그렇게 오랜 시간이 지나고 최근 Rust로 개발된 라이브러리들이 여럿 소개 되면서 나도 다시 Rust로 개발 해보고 마음이 솟구쳤다.\n그래서 이번에 설연휴를 맞아 간단한 프로젝트를 좀 진행해보면 좋겠다는 생각에 “neon”을 이용해서 rust에서 사용하는 jsonwebtoken을 “node-jsonwebtoken” API 호환을 맞춰 node.js용으로 만들어보기로 했다.\n\u0026hellip;\n그리고 만들었다! 두-둥!\nneon-jsonwebtoken Install 후기에 나오겠지만 아주 작은 실수로 배포가 안돼서 3일에 배포할 예정이다.\n$npm i neon-jsonwebtoken Feature Sign jsonwebtoken Decode jsonwebtoken Verify Jsonwebtoken Dependencies and Environments Support Neon Node.js version 12 and higher LTS Rust stable 1.18 and higher Usage 아직 Document를 만들 시간이 충분하지 않았다. 그렇지만 node-jsonwebtoken 과 동일한 API를 유지하려고 했다. 구현되지 않은 부분만 확인한다면 사용하는데는 어렵지 않을 것으로 생각한다. 문서는 조만간 작성하는 것으로 하겠다.\nimport * as jwt from \u0026#39;neon-jsonwebtoken\u0026#39;; const token = jwt.sign(payload, key, signOptions); const decodedPaylaod = jwt.decode(token, decodeOptions); const paylaod = jwt.verify(token, key, verifyOptions); To-Do Asynchronous mutatePayload option in sign function clockTolerance, maxAge, clockTimestamp, nonce options in veirfy function Synchronize Error messages with node-jsonwebtoken Benchmark 가장 인상적인 부분은 Rust 생태계를 이용하여 neon으로 node.js에서 사용할 수 있게 포팅 했을 뿐인데 일반 노드 라이브러리에 비해 성능에서 더 앞서는 수치가 나왔다는 것이다.\n테스트는 각 파일마다 5만번의 iterator를 가지고 진행하였고 테스트마다 10회 씩 반복하여 표준 시간과 최장, 최단 시간을 구하였다.\n테스트 라이브러리는 hyperfine을 사용하였다.\nSign token node-jsonwebtoken은 jws에 의존성을 가지고 있고 callback을 제공한다면 event stream으로 비동기 응답을 제공한다.\nneon-jsonwebtoken은 아직 비동기 응답을 만들지 않았기 때문에 테스트 코드에서 new Promise 로 래핑해서 테스트 해보았는데 동기코드를 Promise로 쌌을 뿐인데 항상 더 빠른 성능이 나온 점에서 이해할 수 없었다. 이에 대하여 자료가 충분하지 않았기 때문에 아래 제공한 데이터에서는 표기하지 않았다.\n❯ hyperfine \u0026#34;node ./node-jsonwebtoken.js\u0026#34; \u0026#34;node ./node-jsonwebtoken-async.js\u0026#34; \u0026#34;node ./neon-jsonwebtoken.js\u0026#34; Benchmark 1: node ./node-jsonwebtoken.js Time (mean ± σ): 1.069 s ± 0.042 s [User: 1.106 s, System: 0.074 s] Range (min … max): 1.019 s … 1.135 s 10 runs Benchmark 2: node ./node-jsonwebtoken-async.js Time (mean ± σ): 1.405 s ± 0.032 s [User: 1.892 s, System: 0.203 s] Range (min … max): 1.367 s … 1.476 s 10 runs Benchmark 3: node ./neon-jsonwebtoken.js Time (mean ± σ): 661.7 ms ± 22.4 ms [User: 629.1 ms, System: 52.1 ms] Range (min … max): 644.0 ms … 705.9 ms 10 runs Summary \u0026#39;node ./neon-jsonwebtoken.js\u0026#39; ran 1.62 ± 0.08 times faster than \u0026#39;node ./node-jsonwebtoken.js\u0026#39; 2.12 ± 0.09 times faster than \u0026#39;node ./node-jsonwebtoken-async.js\u0026#39; Decode token decode에서는 특이하게도 node-jsonwebtoken이 더 좋은 성능을 보여줬다. 여러 이유를 생각해봤지만 이거다 하는 이유는 찾지 못했다. 짐작가는게 있다면 제보해주시면 좋겠다.\n❯ hyperfine \u0026#34;node ./node-jsonwebtoken-decode.js\u0026#34; \u0026#34;node ./neon-jsonwebtoken-decode.js\u0026#34; Benchmark 1: node ./node-jsonwebtoken-decode.js Time (mean ± σ): 1.464 s ± 0.045 s [User: 1.520 s, System: 0.088 s] Range (min … max): 1.414 s … 1.556 s 10 runs Benchmark 2: node ./neon-jsonwebtoken-decode.js Time (mean ± σ): 1.630 s ± 0.041 s [User: 1.701 s, System: 0.088 s] Range (min … max): 1.584 s … 1.698 s 10 runs Summary \u0026#39;node ./node-jsonwebtoken-decode.js\u0026#39; ran 1.11 ± 0.04 times faster than \u0026#39;node ./neon-jsonwebtoken-decode.js\u0026#39; Verify token 토큰 검증에서는 오히려 더 좋은 성능이 나타났다. 테스트 코드는 HMAC 알고리즘에 대해서만 표기했는데 차후 알고리즘 별로 벤치마크 성능을 표기해야겠다.\n참고로 테스트 코드에서는 동일하게 node-jsonwebtoken이 토큰을 발행한 로직이 포함 되어있으므로 sign token에서 node-jsonwebtoken이 걸린 시간만큼 빼줘야 실질적인 시간이 될 것 같다.\n❯ hyperfine \u0026#34;node ./node-jsonwebtoken-verify.js\u0026#34; \u0026#34;node ./neon-jsonwebtoken-verify.js\u0026#34; Benchmark 1: node ./node-jsonwebtoken-verify.js Time (mean ± σ): 2.104 s ± 0.080 s [User: 2.129 s, System: 0.111 s] Range (min … max): 2.003 s … 2.295 s 10 runs Benchmark 2: node ./neon-jsonwebtoken-verify.js Time (mean ± σ): 1.864 s ± 0.118 s [User: 1.875 s, System: 0.104 s] Range (min … max): 1.751 s … 2.120 s 10 runs Summary \u0026#39;node ./neon-jsonwebtoken-verify.js\u0026#39; ran 1.13 ± 0.08 times faster than \u0026#39;node ./node-jsonwebtoken-verify.js\u0026#39; 후기 약 이틀에 걸쳐서 작성했는데 Rust에서 사용되는 jsonwebtoken과 serde serializer, neon에 대해서 파악하는데 시간이 많이 걸렸다.\n평소에는 회사 일로 바쁘니 설 연휴 중에 마무리 지으려고 코드를 짜다보니 정리가 안된 부분도 많이 있다. 아직 러스트 환경에서 코드 아키텍쳐를 어떻게 가져가는지도 확실하게 모르겠고 코드는 차차 리팩토링 해보는 것으로!\nneon이 생각보다 홈페이지가 부실한 부분이 있다. 홈페이지에서는 초기 사용법 정도만 참고하고 나머지는 crate api 문서를 확인하는 편이 좋다.\nnpm publish를 생각없이 했다가 rust src까지 같이 올라가서 취소하고\u0026hellip;\n생각없이 .npmignore에 src만 추가해서 publish 했다가 cargo target 디렉토리가 딸려가서 강제 취소했더니 이미 배포가 되어버렸고\u0026hellip;\n생각없이 npm unpublish를 했다가 하루간 배포할 수 없게 되었다\u0026hellip; 아마 2월 3일 중으로 배포될 듯하다\u0026hellip;\n첫 러스트 프로젝트인데 생각보다 재밌었다. 그리고 trait이라는 개념이 굉장히 매력적이다.\n","permalink":"https://blog.yoonho.site/2022-02-02-rust-nodejs-jsonwebtoken-library/","summary":"정확히 기억은 안나지만 Mozilla Servo가 릴리즈 되었으니 아마도 2016이 맞을거 같다. 그때는 한창 대한민국의 자랑스러운 공군 병장으로서 당당히 전날 야간 근무를 마치고 취침 후 사지방에 있었을 때였다(혹은 주말이어서 비번이었건?). 계기는 모르겠지만 어떤 이유로 Mozilla에서 Servo라는 웹 브라우저","title":"Rust로 만든 node.js용 jsonwebtoken 라이브러리"},{"content":" 쿠키가 마녀에게 잡혀 있던 이유가 있었다.\n오븐브레이크가 아니라 멘탈브레이크였다.\n쿠키런때부터 인성 알아봤다.(인성 문제있어?)\n그렇게 탈출을 도와주려고 했는데\u0026hellip; 쿠키 넌 개인주의야\nintro. 거진 2-3주에 걸친 쿠키 삽질기를 녹여낸 글입니다. 브라우저에서 쿠키를 사용할 때 엄청 애를 먹었습니다. stack overflow나 MDN를 읽는 것만으로 알기 어려운 내용도 일부 포함하였습니다.\n이 글을 통해서 기본적인 쿠키의 개념들과 제가 겪었던 문제의 해결법을 같이 기술하겠습니다.\n나만 빼고 다 알던 기본 개념 쿠키(런)란? 쿠키는 주로 브라우저에 저장되는 HTTP Protocol의 기록 정보입니다. 쿠키는 웹서비스를 이용할때 다양하게 사용이 되는데 쿠키를 제대로 이해하지 못하면 저처럼 multi-domain services을 사용할때 아주 골때리게 됩니다.\n글을 처음 쓸때만 해도 디테일하게 설명하려고 했으나, MDN에 기본적인 내용이 잘 작성 되어있었기 때문에 이 글에서는 제가 겪었던 문제와 해결 방법에 대하여 기술하겠습니다.\n🦸‍♂️ 용감한 쿠키는 오븐을 부수랬더니 내 머리를 부수고 있었다 1년전 코드에 feature를 추가해야할 일이 생겼다. 기존에 로컬 로그인 외에 oauth2 provider를 추가해야 했고 passport를 통해 서비스를 잘 붙였다. 삽질이 좀 있었지만 이정도면 준수한편 “잘 끝났군” 생각하며 로그아웃을 했는데 이게 왠걸 로그아웃이 안됐다. 새로고침을 해도 로그인 정보가 안사라졌다. 로그인이 되면 로그아웃이 되는건 너무 당연한데 왜 안됐을까?\n이유는 토큰 정보를 쿠키에 저장하고 있는데 덮어쓰기가 안되고 있었다. 뭔가 이상해서 기존 로컬 로그인에 토큰 쿠키를 어떻게 세팅하는지 찾아봤다. 맙소사! 토큰을 발급하는 도메인에 로그인하고 응답을 받아 Body를 토큰으로 넣어주는걸 메인 도메인의 Next API에서 처리하고 있었다. 🤦‍♂️\n🦊 구미호 쿠키는 꼬리가 세개만 보인다 이 서비스에서 사용하는 도메인은 6개다.(그래서 진정한 쿠키가 못됐나보다)(우리가 이겼다)\ndomain.com(프론트 메인 도메인) token.domain.com(토큰 발급 도메인) api.domain.com(API 도메인) test.domain.com token.test.domain.com api.test.domain.com (도메인 이름은 임의로 지어냈다)\n이 중 토큰 쿠키를 보유하는 도메인은 domain.com이고 토큰을 발급하는 도메인은 token.domain.com이다. 그리고 api.domain.com은 토큰이 사용되는 도메인이다.\n테스트 도메인의 경우는 테스트 도메인들끼리 통신하며 토큰 안에 aud claim이 test 스테이지를 포함하고 있다.\n로컬 토큰이 발급되는 과정을 먼저 살펴보자면\ndomain.com에서 사용자가 로그인 행위를 시작하면 브라우저에서 username과 password를 받습니다. 브라우저는 domain.com/api/login에 POST method로 username, password를 전송합니다. domain.com/api/login은 token.domain.com에 username과 password를 POST method로 전송합니다. token.domain.com에서 인증 처리가 완료되면 reponse로 token 정보들을 전송합니다. domain.com/api/login은 token 정보를 set-cookie로 응답을 전송합니다. 브라우저는 domain.com/api/login의 응답으로 token 정보를 쿠키에 저장합니다. 반면, 새로운 oauth2 로그인 토큰 발급 과정을 살펴보자면\noauth2.provider.com에는 이미 token.domain.com/oauth2/provider/callback이 등록 되어있습니다.\ndomain.com에서 사용자가 로그인 행위를 시작하면 브라우저는 oauth2.provider.com으로 이동합니다. 브라우저는 oauth2.provider.com에서 로그인을 진행합니다. oauth2.provider.com이 인증을 완료하면 token.domain.com/oauth2/provider/callback으로 redirect합니다. token.domain.om/oauth2/callback은 oauth2.provider.com의 accesss_token, refresh_token을 받아 사용자를 인증합니다. token.domain.com/oauth2/callback은 사용자 인증 후에 응답을 줍니다. set-cookie Header에 cookie domain attribute를 domain.com으로 설정합니다. 응답은 domain.com으로 redirect합니다. 🧟‍♂️ 좀비맛 쿠키는 왜 죽지 않을까? 위의 흐름에서 보면 domain.com에서 set-cookie를 한 token cookie는 따로 domain 설정을 안해줬기 때문에 domain.com으로 쿠키에 저장되었다. 그리고 token.domain.com에서 set-cookie를 한 token cookie는 domain attribute에 domain.com으로 도메인을 정해주었다.\n이쯤에서 내 뇌피셜은 \u0026ldquo;음, domain.com 쿠키가 원래 사용되고 있었고, token.domain.com에서 domain.com 도메인으로 쿠키를 설정했으니 잘 되겠지? 흐흐흫\u0026rdquo; 이런 행복회로를 마구 돌리고 있었다.\n그런데 이상하게도 여전히 로그아웃은 안되고 있었다. 나는 분명히 도메인을 설정해줬고 set-cookie domain.com으로 해줬는데 왜 안될까?\n🧘‍♀️ 요가맛 쿠키는 요가로 마음의 수련을 하고 나는 CircleCI로 인내를 수련한다 몇가지 가정을 세웠다.\n다른 도메인에서 설정해준 쿠키는 도메인별로 관리된다. 즉, 로그아웃 할때 쿠키를 삭제하는 것도 token.domain.com에서 해줘야한다.\nset-cookie attribute 값에 의해 사용되는 쿠키가 다르다.\nexpress에서 cookie를 설정하는 다른 방법이 있다.\nset-cookie할때 overwrite 옵션이 있다.(cookies library) cookieClear를 해줘야한다. secure 설정에 의해 도메인별로 저장되는 쿠키가 다르다.\n예를 들어, secure가 true인 tokens는 https로 바로 전송될 수 있고, false인 tokens는 한번 암호화 해서 저장한 쿠키라던가?\nsameSite 설정에 의해 도메인별로 저장되는 쿠키가 다르다.\n예를 들어, sameSite가 Lax일때 사용되는 tokens라는 쿠키와 None일때 사용되는 tokens라는 쿠키가 다르다던가?\n문제는 도메인에서 set-cookie를 확인해야 하기 때문에 회당 10분이상 걸리는 CircleCI 배포를 테스트마다 돌려줘야 했다. 🤪 결국 위의 모든 방법(그 이상의 더 많은 방법)을 다 테스트 해봐도 결국 해답이 되는 것은 없었다.\n😈 악마맛 쿠키는 악마로 변신한다 결론적으로, 이유는 브라우저 개발자도구로 확인해보니 패킷이 들어올때는 set-cookie에 domain attribute가 domain.com으로 들어오는데 저장될 때는 .domain.com으로 저장되고 있었다. 처음에는 위에서 얘기한 sameSite가 잘못 되었기 때문에 브라우저에서 .domain.com으로 저장되는 줄 알고 sameSite 설정을 건드렸다. 그러나 그건 해결방법이 아니었다. 급한 마음에 메인 도메인의 next api에 다시 작업을 할까 했지만 그러기엔 도메인 역할이 애매하고 작업 공수가 컸다.\n온갖 삽질의 시도 끝에 결국 찾아낸 방법은 cookie를 저장하는 로컬 로그인과 로그아웃의 domain attribute를 .domain.com으로 설정해줬다.\n🏃‍♂️ 쿠키런이 끝날 때는 결국 쿠키가 죽었을때 뿐이다. 뭔가 글을 쓰다 3주의 그 온갖 고생이 한 줄로 요약된 것 같아 현타가 온다 😞\n지금 문득 생각해보니 왜 이렇게 간단한 방법을 왜 그렇게 한참을 헤메고 있었는지\u0026hellip; 머리가 멍청하면 몸이 고생하는 것이었다. 이번 삽질을 통해 얻은 교훈을 정리하면 아래로 정리 할 수 있겠다.\n아래의 가정 중 하나에는 Cookie domain attribute에 prefix로 dot(.)이 붙는 것 같다.(chrome, firefox 기준) domain attribute를 설정해줬을 때 subdomain에서 domain attribute를 설정해줬을 때 2와 같은 경우로 domain attribute가 다르면 cookie가 지워지지 않는다.(overwrite) 위의 이유로 혹시 여러 서브도메인을 갖추고 사용하는 경우, domain attribute를 상시 넣어주는 것이 좋다. Chrome(@^80)의 경우 sameSite를 지정해주지 않았을 경우 sameSite=Lax가 기본 설정이다.(기존 sameSite=None) Firefox의 경우 expires attribute가 현재 시간 이전일 경우 무효된다는 콘솔 메시지가 있으나 Set-Cookie 헤더 자체는 적용되었다가 expires에 따라 즉각 삭제되는 것으로 보인다. Firefox의 경우 sameSite attribute(sameStie=None)가 secure attribute(secure=false) 설정 없이 사용되면 아래의 콘솔 warning을 나타낸다. 곧 유효하지 않도록 조치한다는 의미로 예상된다.\n쿠키 “tokens”는 “SameSite” 속성이 “secure” 속성이 없이 “None”이나 유효하지 않은 값으로 설정되어 있기 때문에 곧 거부됩니다. “SameSite” 속성에 대한 자세한 내용은 https://developer.mozilla.org/docs/Web/HTTP/Headers/Set-Cookie/SameSite를 읽으세요.\ndomain attribute는 depth가 깊은 subdomain도 인식한다.\n.token.test.domain.com에서 발급한 .domain.com 토큰 쿠키를 .test.domain.com에서 사용할 수 있다.\ndomain attribute가 다르면 동일한 name의 쿠키가 존재할 수 있다.\ndomain.com으로 tokens cookie와 .domain.com으로 tokens cookie가 있다면 둘이 공존 할 수 있으며, 우선순위에 따라 브라우저에서 사용된다.\n🧙‍♀️ 결론 마녀 다양한 쿠키를 만들고 능력도 줬는데 쿠키들이 제멋대로 탈출한게 아닐까 싶다. 쿠키들은 당분간 오븐에 아직 갇혀있을 필요가 있다. 쿠키들의 탈출을 도왔던 내 흑역사가 결국 탈출하지 못한채 끝나서 다행이다. 데브시스터즈는 이런 배경 속에 끝나지 않는 맵을 만들었을지 모른다. 쿠키는 잘 쓰면 굉장히 유용하고 보안적인 조치도 많이 되어있다. 하지만 제대로 모르고 사용한다면 오븐이 아니라 내 멘탈이 바사삭 할 수도 있다. 쿠키는 오랜 시간동안 사용되면서 조금씩 보안적 기술이 덧붙여지면서 발전해왔다. 오래된 기술이라고 해서 얕보면 큰코 다칠뿐더러 과거 지식을 가지고 사용했다간 서비스가 망가지기 십상이다. 혹여 내용 중 수정 할 사항(PR) 있거나 질문이(Issue) 있으시면 링크 참고 부탁드립니다. ","permalink":"https://blog.yoonho.site/2020-10-03-http-cookie-break-mental/","summary":"쿠키가 마녀에게 잡혀 있던 이유가 있었다. 오븐브레이크가 아니라 멘탈브레이크였다. 쿠키런때부터 인성 알아봤다.(인성 문제있어?) 그렇게 탈출을 도와주려고 했는데\u0026hellip; 쿠키 넌 개인주의야 intro. 거진 23주에 걸친 쿠키 삽질기를 녹여낸 글입니다. 브라우저에서 쿠키를 사용할 때 엄청 애를 먹었습니다. stack","title":"본격 HTTP 쿠키 삽질기"},{"content":"intro. 너무 당연하게 패스워드는 클라이언트에서 해싱 후에 서버에 보내서 가공해야한다고 생각했습니다. 그게 보안적으로 좀 더 안전하다고 생각했기 때문인데요. 지인에게 2차 비밀번호 평문을 HTTPS(TLS v1.2 이상)로 보냈을 때 무슨 문제가 있는가에 대한 질문을 받았습니다. 저는 당연히 해시를 해서 보내야 한다고 생각만 해봤지 왜인가에 대해서 충분히 생각해보지 못했음을 깨닫고 조사를 해봤습니다. (물론 데이터베이스에 저장할 때는 해시를 한다는 가정입니다.) 그래서 오늘은 HTTPS를 사용할 때 패스워드를 평문을 보내도 되는지에 대해서 조사해봤습니다.\nHTTPS로 평문 패스워드를 보내면 안전한가? 우선, HTTPS로 평문을 보낼때 문제가 있을까요?\n생각해볼 수 있는 경우는 세가지가 있습니다.\nClient Side MITM(Man in the middle) Server Side 이 세가지의 입장에서 살펴보겠습니다.\n1. Client Side 클라이언트의 입장에서 평문을 보낼 때는 적법한 사용자 외에 악성코드, 바이러스 등으로 클라이언트의 정보가 노출되고 있다고 가정하겠습니다.\n이 경우는 해시를 하거나 암호화를 하는 것으로 사용자의 패스워드가 노출 되는 것을 막을 수 없습니다. 혹시, 이미 바이러스에 감염이 되어있었다면 HTTPS 인증서를 통해 도메인에 대한 유효성을 검증하거나 다른 방식의 보안 솔루션을 도입해야합니다.\n2. 중간자 입장에서 중간자는 client-server의 단대단 사이에서 해킹을 통해 통신 패킷을 도청 혹은 조작하는 있는 해커를 의미합니다.\n중간자가 통신 패킷을 볼 수 있다고 하더라도 HTTPS로 패킷이 암호화 되어있기 때문에 유의미한 정보를 얻을 수는 없습니다.\n만약 어떤 방법을 통해 열어 볼 수 있다고 가정한다면, 단순히 패스워드를 해시/암호화 하는 것으로는 재사용 공격(Replay Attack)으로부터 보호할 수 없습니다.\n3. Server Side 서버 입장에서는 패스워드가 평문일 경우 길이/중복문자/사전단어/영문자+숫자+특수문자의 조합/등등의 유효성을 검사할 수 있다는 장점이 있습니다.\n클라이언트가 유효성 검사 후에 해싱하여 보내준다면, 서버는 클라이언트가 유효성 검사를 조작 후에 해시하여 보내줬는지를 파악할 수가 없습니다.\n구글링을 통해 몇몇 블로그, 홈페이지들을 찾아본 결과 HTTPS를 통해 암호를 전송할때 해시/암호화 등의 조치를 한번 더 취하는 것이 사이트 보안 이점을 얻기 어렵다는 글들을 보았습니다. 왜냐하면 공격자가 해시/암호화된 패스워드를 획득하였을 때 서버가 두 경우의 차이를 알 수 없기 때문입니다.(→ 만약, 이 문제(Challenge-Response)에 대한 조치가 취해졌다면 해시/암호화 하는 것과 하지 않는 것의 차이는 없습니다.)\n유일한 이점은 사용자가 여러 사이트에서 동일한 패스워드를 사용하고 있을 때 사용자를 보호한다는 것입니다.(이것이 사이트를 더 안전하게 만들지는 못합니다.)\nProduction 환경에서는 어떻게 쓰일까? 부제: Best Practice를 찾아서\n유명 웹사이트들은 어떻게 사용하고 있을지 궁금해서 대표적인 사이트 몇군데 트래킹 해봤습니다.\n아래의 사이트들의 인증 로직을 다 파악하고 있는 것은 아니므로 어떻게 전달하고 있는지만 봐주시기 바랍니다.\ngoogle, github, twitter: 평문 패스워드 전송 facebook, instagram: 자체 암호 포맷이 있음 네이버: 로그인 창에서 키를 받아오고 암호화? HAMC?을 적용해서 보내는 것으로 추측 RSA 암호화를 하고 있다는 제보를 받았습니다. 카카오: 해시 데이터로 추측 microsoft, linkedin: 평문 패스워드 전송 aws: 평문 패스워드 전송 이상 10개의 사이트를 조사한 결과 국내 포털 사이트와 페이스북 계열 외에서는 평문 암호를 보내는 것을 알 수 있었습니다.\n다만, 쿠키/세션/보안을 위한 코드들과 함께 보안 취약점을 커버하는 데이터들이 함께 전송되는 것으로 파악했습니다.\nConclusion 짧은 내용이었지만 결론을 맺어보겠습니다.\nHTTPS를 사용하여 client-server가 end-to-end 통신을 할때 password를 plain text로 보내는 것보다 hash/encrypt하여 보내는 것이 사이트 입장에서 보안상 이점을 얻는다고 말하기 어렵습니다.\n다만, 서버가 사용하는 HTTPS 인증서가 노출되었을 경우라던지 중간자가 패킷을 도청하였을 경우, hash/encrypt를 통해 사용자를 보호해줄 수는 있습니다.\n또한, HTTPS를 사용한다고 하더라도 그 외의 이중/삼중의 추가적인 보안 솔루션의 도입은 필요하며(위에서 예를든 Challenge-Response 등) HTTPS를 사용하였기 때문에 우리의 로그인 프로세스는 완벽하게 안전하다고 맹신할 수는 없습니다. (CA 인증서 유출, 서버 관리 실책으로 키유출 등)\n#1 HTTPS 해킹 사례 #2 SSL/TLS 공격 #3 TLS 1.3으로 업그레이드 해야하는 이유 추가적인 질문이나 글의 수정사항이 보이신다면 GitHub Issue를 통해 문의해주시면 감사하겠습니다. :)\nReference Is an HTTPS query string secure? - Stack Overflow Is \u0026lsquo;plain text\u0026rsquo;​ password safe to send over network? - LinkedIn Is it ok to send plain-text password over HTTPS? [duplicate] Is an HTTPS query string secure? - Stack Overflow 2020-10-07\u0026hellip; 갑자기 포스트가 여기저기 홍보되기 시작하더니 10월 7일 22시 기준 1.7천 view를 기록했습니다. 방문해주신 모든분들 감사드립니다.\n이렇게 많은 관심을 받게될줄 모르고 부족한 내용임에도 포스팅 했는데 지금 돌아보니 부족한 점이 많습니다. 감사하게도 선배님들의 피드백과 조언을 받고 수정을 조금 거쳤습니다.\n이후 포스트 업데이트나 새글을 일찍 확인하고 싶으시다면! 아래 뱃지를 통해 follow, watch, star를 이용해주세요.\n","permalink":"https://blog.yoonho.site/2020-09-08-https-plain-text-safety/","summary":"intro. 너무 당연하게 패스워드는 클라이언트에서 해싱 후에 서버에 보내서 가공해야한다고 생각했습니다. 그게 보안적으로 좀 더 안전하다고 생각했기 때문인데요. 지인에게 2차 비밀번호 평문을 HTTPS(TLS v1.2 이상)로 보냈을 때 무슨 문제가 있는가에 대한 질문을 받았습니다. 저는 당연히 해시를 해서 보내야","title":"HTTPS를 쓰면 패스워드를 평문으로 보내도 될까?"},{"content":"AUSG 블로그에 Vim 관련 글을 투고했습니다. 많이 봐주세요! 😄\n고인물 개발자는 Vim을 쓴다 이 말이야\n주니어 개발자도 쉽게 사용할 수 있는 Vim IDE를 소개하고자 합니다. SpaceVim이라는 말이 생소하신 분들이 많을 것 같아요. SpaceVim은 spacemacs(emacs 에디터 프레임워크)를 Vim에 맞춰 만든 에디터 프레임워크입니다.\n","permalink":"https://blog.yoonho.site/ausg-monsters-use-vim/","summary":"AUSG 블로그에 Vim 관련 글을 투고했습니다. 많이 봐주세요! 😄 고인물 개발자는 Vim을 쓴다 이 말이야 주니어 개발자도 쉽게 사용할 수 있는 Vim IDE를 소개하고자 합니다. SpaceVim이라는 말이 생소하신 분들이 많을 것 같아요. SpaceVim은 spacemacs(emacs 에디터 프레임워크)를 Vim에","title":"고인물 개발자는 Vim을 쓴다 이 말이야"},{"content":"Intro OAuth 2.0은 인증을위한 산업 표준 프로토콜입니다. OAuth 2.0은 2006 년에 작성된 원래 OAuth 프로토콜에 대한 작업보다 우선합니다. OAuth 2.0은 클라이언트 개발자의 단순성에 중점을 두면서 웹 응용 프로그램, 데스크톱 응용 프로그램, 휴대 전화 및 거실 장치에 대한 특정 권한 부여 흐름을 제공합니다. 이 사양 및 확장은 IETF OAuth Working Group 내에서 개발되고 있습니다.\n- oauth.net의 소개글에서\nOAuth 2.0은 RFC에서 제의된 6749번 문서입니다. OAuth 2.0은 기존의 1.0버전이 가진 보안 취약점, 인증 방식 등을 개선하여 대체하기 위하여 제시되었습니다.\n저는 이전 직장에서 인증 과정을 도입하면서 여러가지 문제점에 부딪혔습니다.\nAWS Cognito/Auth0 같은 서드파티 서비스 이용금지(다양한 이유로) 자체적인 소셜 로그인 구조 필요 Serverless 환경에서 세션 유지 안전하고 검증된 로그인/세션 필요 제3자에게 회사 서비스 API 접근 기능 구현 클라이언트-사이드/서버-사이드 병행 운용 오랜시간 고민하고 검색하면서 공부를 거듭하다가 구글, 페이스북, 네이버 같은 소셜서비스 제공 업체의 로그인 방식을 공부하다가 OAuth라는 인증 과정을 알게되었고 후에 여러 고려사항을 고민한 끝에 이 인증 방법을 도입하기로 결정하였습니다.\nOpenID와 OAuth 두 프로토콜 모두 인증을 위한 프로토콜임은 공통적인 성질로 가지고 있지만, OAuth의 경우 인증과 더불어 허가(인가)의 기능을 내포하고 있습니다. 사용자가 제3자의 서비스를 이용하여 리소스에 접근할 수 있습니다.\n인증(Authentication): 사용자가 적법한 사용자인지 확인. 즉, 로그인 인가(Authorization): 사용자가 요청하는 작업에 적법한 권한을 주는 것. 즉, 권한 확인 예를들면\u0026hellip;\n\u0026ldquo;나\u0026rdquo;(사용자)는 \u0026ldquo;Google\u0026rdquo;(리소스)의 소셜 로그인을 통해 \u0026ldquo;쇼핑몰\u0026rdquo;(제3자의 서비스)에 로그인했다. \u0026ldquo;쇼핑몰\u0026quot;은 \u0026ldquo;내\u0026quot;가 허락한 \u0026ldquo;Google\u0026quot;에서의 \u0026ldquo;내\u0026rdquo; 이름, 이메일, 전화번호를 읽을 수 있다.\nOAuth 1.0 그리고 OAuth 2.0 OAuth 1.0과 OAuth 2.0은 목적만 같은 완전히 다른 프로토콜입니다. 서로 호환도 안되며, 동시 운영할 필요도 없으며, 2.0 자체가 1.0을 대체하기 위해서 나온 프로토콜입니다. 그러므로 이 글에서는 OAuth 2.0만을 설명하겠습니다.\n네가지 역할 OAuth 2.0에서는 네가지 역할이 등장합니다.\nResource Owner(자원 소유자) resource owner:\nAn entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an end-user.\n자원의 소유자. 보호되는 자원에 가장 높은 접근이 가능한 실체입니다. 사람일 경우, 최종 사용자를 가리킵니다. 즉, 대부분의 경우 사용자\nResource Server(자원 서버) resource server:\nThe server hosting the protected resources, capable of accepting and responding to protected resource requests using access tokens.\n자원 서버. 자원을 보호하는 호스팅 중인 서버입니다. 서버는 엑세스 토큰을 사용하여 보호 중인 자원에 대한 요청을 처리합니다. 예를 들어, 구글, 페이스북 같은 소셜 서비스 제공자\nClient(클라이언트) client:\nAn application making protected resource requests on behalf of the resource owner and with its authorization. The term \u0026ldquo;client\u0026rdquo; does not imply any particular implementation characteristics (e.g., whether the application executes on a server, a desktop, or other devices).\n자원의 사용자. \u0026ldquo;자원 소유자\u0026quot;를 대신하여 자원 소유자의 인가로 보호되는 자원에 요청하는 어플리케이션. \u0026ldquo;클라이언트\u0026quot;라는 용어는 특정 구현 특성(예컨데, 서버, 데스크탑, 혹은 다른 기기들 위에서 실행되는 어플리케이션)을 의미하지 않습니다. 예를 들어, 앱, 쇼핑몰, 게임 등 소셜 로그인 이용자(업체)\nAuthorization Server(권한 부여 서버) authorization server:\nThe server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorization.\n권한 부여 서버. \u0026ldquo;자원 소유자\u0026quot;와 성공적인 인증과 권한 부여를 획득 후에 \u0026ldquo;클라이언트\u0026quot;에게 엑세스 토큰을 발행하는 서버. 예를 들어, 구글, 페이스북 같은 소셜 서비스 제공자의 권한 부여 서버\n\u0026ldquo;Resource Server\u0026rdquo;(자원 서버)와 \u0026ldquo;Authorization Server\u0026rdquo;(권한 부여 서버)는 같은 서버일 수도 있고 별개의 서버일 수도 있습니다. 그것은 개발자의 자유입니다. 상황과 환경에 맞춰서 구성하는 것이 좋습니다.\nProtocol Flow 이해하기 쉽게 그림을 그려왔습니다.(아이패드 짱짱)\n차근히 살펴보자\n클라이언트는 자원 소유자에게 허가를 요청한다. 허가는 자원 소유자에게 바로 요청하거나 **권한 부여 서버가 중개자로서 간접적(바람직)**으로 이루어질 수 있습니다. 클라이언트는 자원 소유자의 인가를 나타내는 권한 부여를 받습니다. 권한 부여 유형은 4가지 방식 중 하나를 사용하거나 확장된 유형으로 사용할 수 있습니다. 권한 부여 유형은 클라이언트의 요청과 권한 부여 서버가 지원하는 타입에 따라 다릅니다. 클라이언트는 권한 부여 서버에게 권한 부여 허가에 따라 액세스 토큰을 요청합니다. 권한 부여 서버는 클라이언트를 인증하고, 권한 부여 허가를 검증합니다. 만약 잘 되었다면, 액세스 토큰을 발행합니다. 클라이언트는 자원 서버에게 보호된 자원을 요청합니다. 그리고 액세스 토큰으로 인증합니다. 자원 서버는 액세스 토큰을 검증합니다. 만약 잘 되었다면, 클라이언트의 요청에 응답합니다. 2부에서는 대표적인 4가지 Authorization Grant의 흐름을 살펴보겠습니다.\nReference RFC 6749 - The OAuth 2.0 Authorization Framework OAuth 2.0 - OAuth ","permalink":"https://blog.yoonho.site/2019-11-06-oauth2-1/","summary":"Intro OAuth 2.0은 인증을위한 산업 표준 프로토콜입니다. OAuth 2.0은 2006 년에 작성된 원래 OAuth 프로토콜에 대한 작업보다 우선합니다. OAuth 2.0은 클라이언트 개발자의 단순성에 중점을 두면서 웹 응용 프로그램, 데스크톱 응용 프로그램, 휴대 전화 및 거실 장치에 대한 특정 권한 부여","title":"OAuth2.0 완벽 정리(1)"},{"content":"\n변수와 상수 이번엔 프로그래밍의 가장 기본이 되는 변수와 상수 선언을 살펴볼까요?\nGo Go는 변수 선언시 var 예약어를 사용합니다. 형태는 var 변수명 타입을 이루고 있습니다. Javascript에서 사용하는 var와 이름이 같네요 ㅎㅎㅎ\nvar x, y, z int // 0 0 0 var c, python, java bool // false false false 변수를 초기화할 수도 있습니다. 변수를 초기화하는 경우 타입을 생략할 수 있습니다.\nvar x, y, z int = 1, 2, 3 // 1 2 3 var c, python, java = true, false, \u0026#34;no!\u0026#34; // true false no! 함수 안에서 지역변수를 선언할 경우 단축 예약어를 사용할 수 있습니다.\nfunc a() { var c, python, java = true, false, \u0026#34;no!\u0026#34; // true false no! } /* OR */ func b() { c, python, java := true, false, \u0026#34;no!\u0026#34; /// true false no! } 그럼 상수는 어떻게 선언할까요? 상수는 const 예약어를 사용합니다. 상수는 타입의 제약이 있습니다. 다음의 타입만 상수로 정의할 수 있습니다.\n문자(character) 문자열(string) 부울(boolean) 숫자 const Pi = 3.14 func main() { const World = \u0026#34;안녕\u0026#34; const Truth = true } 그런데 숫자형 상수는 좀더 정말한 값을 사용할 수 있습니다. 타입을 지정하지 않은 상수는 문맥(context)에 따라 타입을 가지게 됩니다.\npackage main import \u0026#34;fmt\u0026#34; const ( Big = 1 \u0026lt;\u0026lt; 100 // 비트 연산 2^100 = 1.2676506E30 Small = Big \u0026gt;\u0026gt; 99 // 비트 연산 Big/2^99 = 2^1 = 2 ) func needInt(x int) int { return x * 10 + 1 } func needFloat(x float64) float64 { return x * 0.1 } func main() { fmt.Println(needInt(Small)) // 21 = 2 * 10 + 1 fmt.Println(needFloat(Small)) // 0.2 = 2 * 0.1 fmt.Println(needFloat(Big)) // 1.2676506002282295e+29 } Rust 이번엔 Rust를 살펴보겠습니다. Rust는 안전한 메모리 관리를 위해서 특별한 개념을 사용합니다. 이 개념은 나중에 살펴보고 일단 변수와 상수를 먼저 알아볼까요?\nRust는 다른 언어들과 달리 변수를 기본적으로 상수처럼 사용합니다. 정확히 말하면 변할 수 없는(immutable) 변수(variable)을 사용합니다. 예약어는 let을 사용합니다. 다음의 예제는 4번째 줄에서 컴파일러단 에러가 나옵니다. immutable variable은 변경할 수 없습니다.\nfn main() { let x = 5; println!(\u0026#34;The value of x is: {}\u0026#34;, x); x = 6; println!(\u0026#34;The value of x is: {}\u0026#34;, x); } Rust는 특이하게도 이런 문제를 일으킬수 있을만한 변수는 원천적으로 불편성을 가지게 합니다. mutable variable을 선언하기 위해서는 mut를 같이 적어줍니다.\nfn main() { let mut x = 5; println!(\u0026#34;The value of x is: {}\u0026#34;, x); x = 6; println!(\u0026#34;The value of x is: {}\u0026#34;, x); } Rust는 Shadowing이라는 기법을 통해 변수를 mutable하지 않게 안정적으로 사용할 수 있습니다. 다음을 볼까요?\nfn main() { let x = 5; let x = x + 1; let x = x * 2; println!(\u0026#34;The value of x is: {}\u0026#34;, x); } 위 코드의 결과로 최종 x는 12의 결과를 가집니다. 이 방식과 mutable variables의 차이점은 Shadowing을 사용하면 마지막으로 let으로 선언한 변수 이후로는 더이상 변경 할 수 없다는 것입니다.\n조금은 어려워 보이는 이러한 Rust만의 방식은 가비지 콜렉터 없이 안전한 메모리 사용을 할 수 있도록 합니다.\n그런데 무려 상수는 따로 있습니다!! Rust에서 상수는 const 예약어를 사용합니다. Rust의 상수 명명 규칙은 대문자 구성의 문자열과 _의 사용합니다. 또한 가독성을 위해 숫자 사이에 _를 넣을 수 있습니다. 다음은 100,000 값을 가진 MAX_POINST 라는 상수입니다.\nconst MAX_POINTS: u32 = 100_000; 불변 변수(?)와 다른점이 궁금하실텐데요. 정리해드리겠습니다.\nmut와 const는 함께 사용할 수 없습니다. 상수는 항상 불변성을 가지고 있습니다. 모든 범위에서 const 상수를 선언하고 읽을 수 있습니다. 상수는 오직 상수 표현식으로만 선언할 수 있으며, 함수의 결과나 런타임시에 계산할 수 있는 다른 값은 안됩니다. 요약 | 예약어 | Go | Rust | | \u0026mdash; | \u0026mdash; | \u0026mdash; | | 변수 | `var` | `let`(immutable) or `let mut`(mutable) | | 상수 | `const` | `const` |\n이번 글의 생각 일단 컴파일 언어에서 var, let, const와 같은 예약어가 등장해서 Javascript 유저로서 굉장히 친근했습니다 ㅎㅎ\n이번 포스팅을 준비하면서 생소했던 점은 Go보다 Rust에서 더 많았던거 같아요. 우선 이번 글에서 다루지는 않았지만 Rust에서 사용되는 소유권이라는 개념을 위해서 변할수 없는 변수가 \u0026ldquo;이걸 변수라고 표현해도 되는건가 ㅋㅋㅋ\u0026rdquo; 하는 생각이 들었습니다.\n다음 포스팅은 Data Types을 주제로 쓰겠습니다.\nReference 변수 (Variables) - A Tour of Go Variables and Mutability - The Rust Programming ","permalink":"https://blog.yoonho.site/go-rust-programming-basic-variables-constants/","summary":"Golang과 Rust 변수와 상수 이번엔 프로그래밍의 가장 기본이 되는 변수와 상수 선언을 살펴볼까요? Go Go는 변수 선언시 var 예약어를 사용합니다. 형태는 var 변수명 타입 을 이루고 있습니다. Javascript에서 사용하는 var 와 이름이 같네요 ㅎㅎㅎ var x, y, z int // 0 0 0","title":"변수와 상수 - 고랭? 러스트가 그렇게 좋다며?(2)"},{"content":"\nHello, World!, 안녕 우선, 문법을 보기에 앞서서 두 언어의 가장 기본이 되는 메인 함수를 한번 봐불까요?\n// main.go package main import \u0026#34;fmt\u0026#34; func main() { fmt.Println(\u0026#34;Hello, 안녕\u0026#34;) } // main.rs fn main() { println!(\u0026#34;Hello, world!\u0026#34;); }\n두 언어 다 main()이라는 함수로 호출하네요.\nGo는 main 패키지에서부터 시작해서 \u0026quot;fmt\u0026quot; 패키지를 import해서 사용하고 있네요. Rust는 main 함수만 작성했습니다. 첫 인상은 Rust가 시작이 간단해서 좋네요.\n이어서 봐볼까요? 둘 다 console에 각각 \u0026ldquo;Hello, 안녕\u0026rdquo;, \u0026ldquo;Hello, world!\u0026ldquo;를 출력해주고 있네요. Go는 C언어처럼 fmt라는 패키지에서 Println()을 호출해서 사용하고 있네요. Rust는 표준출력이 기본으로 빌트인된 함수인가 봅니다. println!()를 호출해서 사용하고 있습니다. 그리고 Go언어와는 다르게 식의 끝에는 ;를 붙여줍니다.\n컴파일 Go는 작업 디렉토리 안에서 $ go build를 실행하면 .go 확장자가 컴파일이 되어 실행 바이너리 파일이 output 됩니다.\nRust는 작업 디렉토리 안에서 $ rustc main.rc를 실행하면 .rs 확장자가 컴파일이 되어 실행 바이너리 파일이 output 됩니다.\n둘 다 빌드는 간단하네요. 명령어도 간단합니다.\n패키지 두 언어는 모두 패키지 개념을 가지고 있습니다. 의존성 라이브러리/패키지를 관리합니다.\n패키지 관리자 각 언어에는 패키지 매니저가 있습니다. node.js의 npm/yarn 같은 친구입니다.\nGo의 Go modules Go는 1.11 버전부터 자체적으로 Go modules라는 패키지 매니저로 통합 되었습니다. 각 패키지 매니저에 대한 자세한 사용법은 나중에 분리해서 작성하고 여기는 가볍게 살펴보고 넘어가겠습니다.\ngo mod init Go modules가 생성하는 프로젝트 관리 파일은 go.mod입니다.\nRust의 Cargo Rust는 Cargo라는 패키지 관리자가 있습니다. cargo는 node의 패키지 매니저처럼 프로젝트를 생성하고 스크립트를 실행하는 등의 작업을 할 수 있네요.\ncargo new cargo build cargo run Cargo를 통해 프로젝트를 생성하면 Cargo.toml이라는 파일이 생성되는데 npm의 package.json 같은 프로젝트 관리 파일입니다.\n패키지 사용법 Go // math.go package main import ( \u0026#34;fmt\u0026#34; \u0026#34;math\u0026#34; ) func main() { fmt.Println(\u0026#34;Happy\u0026#34;, math.Pi, \u0026#34;Day\u0026#34;) } Go는 import 명령어를 이용해서 패키지를 가져올 수 있습니다. 위의 예시처럼 import (~~~, ~~~~) 콤마로 구분하셔도 되구요.\nimport \u0026#34;fmt\u0026#34; import \u0026#34;math\u0026#34; 이렇게 작성하셔도 됩니다.\n패키지명은 디렉토리 경로의 마지막 이름만 사용하는 것이 규칙이라고 하네요.\n예)\n경로: path/filepath\n사용: import \u0026quot;filepath\u0026quot;\n또한, Go 언어에서는 패키지에서 함수나 변수, 상수 등을 패키지 외부로 내보내고 싶을 때 다른 예약어가 없이 첫 글자를 대문자로 작성해주어야 합니다. 위의 예제에서는 math.Pi를 자세히 보시면 p가 아니라 P입니다. 흠 이건 조금 호불호가 갈리겠네요. 전 좀더 사용해봐야 결정 할 듯 합니다.\nRust 이번엔 Rust를 살펴볼까요?\nuse std::io; fn main() { println!(\u0026#34;Guess the number!\u0026#34;); println!(\u0026#34;Please input your guess.\u0026#34;); let mut guess = String::new(); io::stdin().read_line(\u0026amp;mut guess) .expect(\u0026#34;Failed to read line\u0026#34;); println!(\u0026#34;You guessed: {}\u0026#34;, guess); } Rust는 use 예약어를 사용합니다. 예약어 뒤에 std::io 패키지 이름을 작성해줍니다. 여러 패키지를 쓰고 싶을 때는 줄바꿈 후에 use ~~;를 작성해주시면 됩니다.\nuse std::io; use rand::Rng; 이번 글의 생각 제가 보기엔 두 케이스 모두 예약어 뒤에 하나의 패키지씩 작성하는게 보기 좋을 것 같아요. Go도 매 줄마다 ㅎㅎㅎㅎ\n두 언어 모두 생소하거나 조금씩 저의 호불호가 갈리는 부분들이 있는데요. Go의 경우 패키지에서 Export 할 때 첫글자를 대문자로 써준다는게 굉장히 낯서네요;;;; Rust의 경우에는 아직까지는 특별한 것은 없으나 ;를 적어줘야 하는 부분이 좀 너무 올드하지 않나 하는 생각이 듭니다.\n이번 글은 여기까지구요. 다음번엔 변수, 상수, 함수 같은 기본 프로그래밍 문법에 관하여 작성하겠습니다. 안녕!\nReference Go 패키지관리 A Tour of Go Hello, World! - The Rust Programming ","permalink":"https://blog.yoonho.site/go-rust-programming-hello-world/","summary":"Hello, World!, 안녕 우선, 문법을 보기에 앞서서 두 언어의 가장 기본이 되는 메인 함수를 한번 봐불까요? // main.go package main import \u0026ldquo;fmt\u0026rdquo; func main() { fmt.Println(\u0026ldquo;Hello, 안녕\u0026rdquo;) } // main.rs fn main() {","title":"Hello, World! - 고랭? 러스트가 그렇게 좋다며?(1)"},{"content":"그렇습니다. 제목은 어그로를 끌려는 저의 작전이었던 것입니다.\n스크립트 언어 덕후인 제가 오랜만에 컴파일 언어를 보게 될 일이 있었습니다. 바로 Go언어와 Rust인데요. 사실 둘다 나온지는 좀 됐죠? 옛날에도 배우고 싶어서 검색하고 알아본적은 있었지만, 당시에는 너무 초기여서 비교하거나 배울 필요성을 못느끼고 있었습니다. 그런데 오랜만에 들고나온 이유는 Google이 Go언어를 엄청 밀어주면서 Docker, k8s 등에 엄청 쓰이고 있고, Rust는 웹친화적인 언어 성향과 뛰어난 최적화와 메모리 관리로 Golang 이상의 성능을 보여주고 있죠.\nGo is an open source programming language that makes it easy to build simple, reliable, and efficient software.\nGo는 소프트웨어를 쉽고, 안정적이며, 효율적으로 빌드하도록 만들어주는 오픈소스 프로그래밍 언어입니다.Go 홈페이지 첫 화면 문구\nA language empowering everyone to build reliable and efficient software.\n(Rust는) 모든 사람이 소프트웨어를 안정적이며 효율적으로 빌드하게 해주는 언어입니다.Rust 홈페이지 첫 화면 문구\n그럼 둘 다 안정적이고 효율적이면, simple이 들어간 Golang이 승리? 그리고 그것은 사실이 되었다.\n아무튼 그래서 기본적인 프로그래밍 문법이나 용법들을 살펴보면서 Golang과 Rust에 대해 배워보는 시간을 가져보고자 합니다. 각 언어의 문법을 배우시고 싶으신 분들은 더 좋은 레퍼런스, 도큐먼트가 있을테니 그곳을 참고하시구요. 또한 홈페이지에 들어가시면 도큐먼트가 상세하게 나와있습니다.\n이 시리즈는 그저 두 언어를 비교하면서 배워보고자 하는게 컨셉이니 너무 타이트하게 생각하지 마시고 여유있게 따라오시면 두 언어를 동시에 재밌게 배울 수 있을 것 같습니다. 중간중간 다른 언어와 비교할 수도 있습니다. JS라든가 Python이라든가\n그럼 \u0026ldquo;고랭? 러스트가 그렇게 좋다며?\u0026rdquo; 시리즈 시작합니다.\nReference The Go Programming Language Rust Programming language Golang vs Rust 퍼포먼스 벤치마킹 썰 - 이학진 ","permalink":"https://blog.yoonho.site/go-rust-programming-intro/","summary":"그렇습니다. 제목은 어그로를 끌려는 저의 작전이었던 것입니다. Golang과 Rust 스크립트 언어 덕후인 제가 오랜만에 컴파일 언어를 보게 될 일이 있었습니다. 바로 Go언어와 Rust인데요. 사실 둘다 나온지는 좀 됐죠? 옛날에도 배우고 싶어서 검색하고 알아본적은 있었지만, 당시에는 너무 초기여서 비교하거나 배울","title":"고랭? 러스트가 그렇게 좋다며?(0)"},{"content":" 주의! 이 글은 경력자로서 작성한 정보 전달의 글이 아닙니다. 공부한 내용을 정리하기 위한 글임을 명심해주시고, 관련하여 조언이 있으시면 언제든지 하단의 댓글을 통해 혹은 PR을 통해 아낌없는 조언 부탁드립니다.\n이전 회사에서 개발하면서 DevOps를 사용하고 있었는데, 보안 전공자로서 모든 개발, 배포, 운영 과정에서 자연스럽게 보안에 대한 부분들을 고려하면서 개발했습니다. 그때는 *\u0026ldquo;당연히 모든 과정에서 보안 부분을 검토해야지\u0026rdquo;*하는 생각에 내가 DevSecOps를 하고 있다는 자각이 없었는데, 이후 DevSecOps를 알고 나니 좀 더 공부할 필요가 느껴졌습니다.\n이 글은 그 이후에 관련된 직종으로 이직을 준비하면서 정리하는 글입니다.\nDevSecOps란 DevSecOps = DevOps + Security\n기존에 보안은 개발의 최종단계로써 분리되었습니다. 그러나 보안이 개발 Pipeline에 유기적으로 결합 되어있지 않으면, 최종단계에서 보안 점검 중 심각한 보안 결함을 발견할 때 이는 개발 소스 전체에 영향을 줄 수 있는 Critical Risk입니다. 이러한 Risk는 며칠 혹은 몇 주의 개발 주기를 갖는 개발 환경에서 전체적인 효율성을 떨어뜨리는 원인으로 인식되었습니다. 따라서 이제는 협력적인 DevOps Framework에서 보안은 공동의 책임이며 처음부터 통합되어야 합니다.\n즉, DevSecOps는 처음부터 애플리케이션과 인프라 보안을 고려해야 한다는 것입니다. 또한 DevOps 워크플로우가 느려지지 않도록 보안 게이트를 자동화해야 합니다.\n좋은 DevSecOps를 구축하기 위해서는 개발, 운영, 보안의 모든 부서가 보안은 공동 책임이라고 생각해야 한다. 업무 프로세스 초기부터 모든 개발자가 보안에 대한 이해를 바탕으로 개발하며, 필요하다면 Secure Coding을 학습해야 한다. DevOps CI/CD Pipeline에 효율성과 정확성을 위한 보안 프로세스 자동화가 필요합니다. DevOps CI/CD Pipeline에 잘 융화될 수 있도록 보안 프로세스 관련 Tools를 현명하게 선택해야 합니다. 자동화를 통한 DevOps 보안 기업 환경에서의 서비스 규모가 거대해지고 다양한 개발 환경들이 제공되면서 개발자들은 더 다양하고 편리한 방법들을 도입하여 서비스와 개발 품질을 높이고 있습니다. 이런 환경 속에서 일일이 수동적인 보안 프로세스를 거치는 것은 프로세스 배포 주기를 늦추고 효율을 저하합니다.\n따라서 DevOps 과정에서 반복적인 보안 테스트를 진행함으로써 보안 취약점 점검 과정을 단순화 할 수 있습니다.\n장점 관리상의 잘못과 실수가 줄어든다. 보안 설계자가 보안 콘솔을 수동으로 구성할 필요성을 줄여준다. 지속해서 보안이 향상된다. 클라우드에서의 DevSecOps 점차 엔터프라이즈급의 개발환경이 클라우드 환경으로 변화됨에 따라 오픈되고 단일화된 API(like REST-API, GraphQL 등)이 제공되기 시작합니다. 이에 따라 보안에 대한 중요성도 증가하였습니다.\nDevOps 개발 프로세스 내에서 보안 테스트를 진행할 수 있으며, 취약점을 점검할 수 있습니다. 이는 DevOps 프로세스가 진행되면서 점차 애플리케이션이 보안 측면에서 안전하게 되는 것을 의미합니다.\nReference.2의 글에서 \u0026ldquo;컨테이너 및 마이크로서비스를 위해 구축된 DevOps 보안\u0026quot;에 대한 섹션이 있는데 이 부분은 더이상 정리할 게 없을 정도로 잘 되어있기 때문에 링크를 따라 들어가 한번 읽는 것을 추천합니다.\n결론 정리하면서 든 생각은 결론적으로 모든 개발 과정에서 *\u0026ldquo;보안은 마지막\u0026rdquo;*이라는 인식이 사라지는 것이다. 이는 개발한다, 운영한다는 의미 속에 전범위적으로 보안을 적용한다는 것이다. 즉, **\u0026ldquo;보안을 고려하여 개발하고 운영한다\u0026rdquo;**는 의미이다. 보안을 고려한다는 것은 쉬운 문제가 아닐 수 있다. 그러나 이 장벽은 더 나은 결과를 위한 투자에 불과할 것이다.\nReference 보안은 개발부터!! 데브섹옵스(DevSecOps) - LG CNS DevSecOps란 무엇일까요? - Red Hat 데브섹옵스를 시작하는 5가지 방법 - ITWorld Korea 데브섹옵스란 무엇인가, 더 안전한 애플리케이션 개발하기 - ITWorld Korea ","permalink":"https://blog.yoonho.site/2019-10-21-devsecops-study/","summary":"주의! 이 글은 경력자로서 작성한 정보 전달의 글이 아닙니다. 공부한 내용을 정리하기 위한 글임을 명심해주시고, 관련하여 조언이 있으시면 언제든지 하단의 댓글을 통해 혹은 PR을 통해 아낌없는 조언 부탁드립니다. 이전 회사에서 개발하면서 DevOps를 사용하고 있었는데, 보안 전공자로서 모든 개발, 배포, 운영 과정에서","title":"DevSecOps에 관하여"},{"content":"얼마전 카카오, 네이버, 라인 코딩 테스트를 봤다고 포스팅 했었는데요. 드디어 네이버에서도 결과가 나왔습니다. 사실 결과가 나온지는 조금 됬습니다. 바빠서 이제야 포스팅하게 됐네요.\n아마 제목을 통해서나 이 글을 썼다는 시점에서 예상하신 분들도 계시겠지만 \u0026ldquo;1차 합격\u0026quot;했습니다. 짜잔!😎\n후기라고 할게 있는지 잘 모르겠습니다. 소감이라고 한다면 네이버 코딩 테스트를 비록 부족했을지라도 합격점을 받았다는 것이 감격입니다. 그리고 이번 주에 있을 면접도 굉장히 기대가 됩니다. 어려울수도 있고 탈탈 털리고 올수도 있구요. 그렇지만 그 시간 자체를 즐기고 와볼 생각입니다.\n앞으로 얼마나 더 갈 수 있을지 많은 것들을 보고 배우고 해보고 경험할 수 있을지 두근두근합니다 ㅎㅎㅎ. 면접 보고 와서 면접 후기도 포스팅 해보겠습니다.\n궁금하신거나 질문이 있으시다면 언제든지 밑에👇👇 댓글 달아주시면 답변 드리겠습니다.\n","permalink":"https://blog.yoonho.site/2019-10-10-2019-naver-recruit/","summary":"얼마전 카카오, 네이버, 라인 코딩 테스트를 봤다고 포스팅 했었는데요. 드디어 네이버에서도 결과가 나왔습니다. 사실 결과가 나온지는 조금 됬습니다. 바빠서 이제야 포스팅하게 됐네요. 아마 제목을 통해서나 이 글을 썼다는 시점에서 예상하신 분들도 계시겠지만 \u0026ldquo;1차 합격\u0026quot;했습니다. 짜잔!😎 후기라고 할게 있는지 잘","title":"네이버 신입 공채 1차 합격"},{"content":"2019년 10월 7일에 macOS 카탈리나가 정식 출시 되었습니다. 저는 잊어 버리고 있다가 어제 유튜버들이 리뷰한걸 보고 오늘에서야 부랴부랴 업데이트했습니다. ㅎㅎㅎㅎ\n이번 업데이트에서 가장 기대했던 점은 개인적으로 Sidecar 기능인데요. iPad를 보조 모니터로 사용할 수 있는 기능입니다. 바로바로 듀얼 모니터!!! 세상에나 이젠 어디서나 듀얼모니터라니 넘 좋지 않나요? ㅠㅠㅠ 심지어 애플펜슬도 사용할 수 있어요.\n아침에 눈뜨자마자 오전 중에 업데이트하려고 맥북을 열고 업데이트를 눌렀더니 이게 왠일\u0026hellip; 한 700MB정도 받고나서부터는 점점 느려지더니 업데이트 시간이 무려 2일\u0026hellip; 실화..?\n마저 업데이트를 다 못하고 오후에 카페에서 업데이트를 진행해봤는데요. 스타벅스 효과인지, 시간이 지나서인지, 저희 집 네트워크가 문제였던건지 여기서는 순식간에 설치했습니다.\n이번 업데이트로 정말 다양한 기능들이 추가되었는데요. 애플 홈페이지에서 확인할 수 있습니다.\nApple Music, Podcasts iTunes에서 음악, 팟캐스트가 각각 Apple Music 앱과 Apple Podcasts 앱으로 분리되었습니다. 기존에 있던 기능들은 모두 그대로 사용 할 수 있으며, 동기화는 iCloud를 통해 백그라운드에서 자동으로 진행됩니다. 또한 Finder에서 기기를 직접 연결하여 관리할 수 있습니다.\nMac Catalyst 개발자들이 기존 iPad 앱을 Mac용 앱으로 쉽게 포팅할 수 있게 되었습니다. 잠재적으로 굉장히 기대가 되는 기능입니다. 아직은 제공되는 앱이 별로 없을 것으로 생각되지만 유용한 iPad 앱이 Mac용으로 나오는 것들이 있으면 포스팅 해보겠습니다.\n기본 앱의 변화 사진, 메모, 미리 알림, Safari가 기존 iOS와 iPadOS에서 업데이트된 것과 같이 macOS에서도 업데이트 되었습니다. 저는 지금 GoodNote와 MS OneNote를 주로 사용하고 있는데, 써봐야 알겠지만 만약 메모 기능이 카테고리 기능이라던가 태그 기능이 잘 지원된다면 옮겨가야겠네요.\nSidecar iPad를 Mac의 보조 디스플레이로 활용할 수 있습니다. 제가 제일 기다리던 기능!! 이제 어디서나 듀얼모니터로 작업할 수 있습니다. 넘넘 좋아요 ㅠㅠㅠ\n심지어 애플 펜슬을 사용하면 화면에 펜슬로 그림도 그릴 수 있어요(아직 얼마나 필요한 기능인지는 아직 잘 모르겠지만요). 제 생각엔 크리에이터들에게 많이 필요한 기능인 것 같아요.\n스크린타임 저에겐 별로 흥미 없는 기능 쿨하게 Pass!\n보안 기능 강화 보안 기능이 강화되었습니다.\nmacOS 설정 변경 보호 안전한 앱만 사용 데이터 접근 관리 도난시 더 쉽게 찾기 Apple Watch를 통해 인증 등 음성 명령 이젠 음성 명령만으로 맥북을 사용하기 더욱 좋아졌습니다. 심지어 한국어도 지원해요! 대박쓰!! 열일하는 애플사. 벗어날 수 없다\u0026hellip;\n결론 이번 업데이트는 정말이지 심쿵하게 만드는 업데이트 같아요. 이래서 애플 제품만 쓰게 되는 것 같아요. 다음 업데이트가 계속 기다려집니다. ㅎㅎ 그럼 오늘 여기서 끝\n","permalink":"https://blog.yoonho.site/2019-10-10-macos-catalina-release/","summary":"2019년 10월 7일에 macOS 카탈리나가 정식 출시 되었습니다. 저는 잊어 버리고 있다가 어제 유튜버들이 리뷰한걸 보고 오늘에서야 부랴부랴 업데이트했습니다. ㅎㅎㅎㅎ 이번 업데이트에서 가장 기대했던 점은 개인적으로 Sidecar 기능인데요. iPad를 보조 모니터로 사용할 수 있는 기능입니다. 바로바로 듀얼","title":"macOS Catalina 정식 출시"},{"content":"\n2019년 하반기 카카오(신입), 네이버(신입), 라인(인턴 전환)에서 정규직 채용 코딩 테스트를 봤습니다. 기업 기술 순서는 그저 테스트 시험일 순입니다.\n코딩 테스트 경험이 없어서 긴장을 많이 했었습니다.\n카카오의 경우 블라인드 채용이라 테스트를 먼저 봤고, 네이버와 라인은 서류가 먼저 있었습니다. 그렇지만 라인의 경우 서류라고 해도 간단한 인적사항만 넣어서 제 생각엔 아무 생각 없이 지원하는 사람들 선별하려고 넣은 과정이 아니었나 생각했습니다.\n세 곳 모두 프로그래머스에서 테스트를 진행했습니다. 프로그래머스에서 테스트나 프로그래머스에서 제공하는 알고리즘을 풀어보신 분들은 아시겠지만, 프로그래머스는 \u0026ldquo;실행\u0026quot;과 \u0026ldquo;제출\u0026quot;로 나뉘어집니다. \u0026ldquo;실행\u0026quot;은 문제에서 제공해주는 테스트 케이스를 실행해서 결과를 보여주는 것이구요. \u0026ldquo;제출\u0026quot;은 완성한 알고리즘을 전송하면 내부적으로 응시자가 알 수 없는 테스트 케이스를 실행하면서 정확성(과 효율성)을 체크합니다. 또한 제출된 문제들은 언제든지 몇 번 문제를 풀지 선택할 수 있습니다.\n테스트 타임 카카오 5시간 네이버 2시간 라인 3시 시험 시간의 경우 카카오가 제일 길었습니다. 그렇지만 단점도 있었는데요. 카카오의 경우 코드를 제출하면 테스트가 진행되더라구요. 그런데 이 테스트 케이스가 정확성 몇 개, 효율성 몇 개 이렇게 실행이 되는데 단 하나만 실패해도 통과가 안됩니다. 저의 경우 예를 들어 1번 문제에서 정확성 테스트만 50개였다면 49/50개가 성공해서 1개 때문에 1번 문제 제출이 안됐습니다. 3? 4?번 문제도 마찬가지로 정확성 30/30, 효율성 4/5로 통과를 못했습니다. 그러다보니 계속 그 문제에 집착하게 되고 계속 다른 문제로 넘어가지 못하고 있었습니다. 그러다가 무려 5시간임에도 불구하고 카카오 문제는 한문제도 통과를 못했습니다. 겨우 두 문제 풀고 붙잡고 있었어요\u0026hellip;. ㅠㅠ\n네이버와 라인은 그런 부담이 없었습니다. 실행은 가능하나 제출하면 테스트가 돌지 않고 그냥 제출로 끝납니다. 그래서 개인적으로 열심히 생각해보고 문제 없겠다 생각이 들면 그냥 다른 문제로 넘어가서 풀면 됐습니다. 그래서 네이버와 라인은 훨씬 적은 시간임에도 모든 문제를 볼 수 있는 시간적 여유가 충분했습니다. 다만, 시간이 적다보니 상당이 쫄깃쫄깃 스릴 넘치는 맛이 있습니다\u0026hellip; ㅎ;\n문제 갯수 카카오 6문제 네이버 3문제 라인 6문제 문제 갯수는 사실 별로 할 말이 없는게 문제에 익숙한 정도의 차이인 것 같아요. 알고리즘 문제를 많이 풀어보면 답에 대한 접근 방향이 빨리 서겠더라구요. 알알못인 저에게는\u0026hellip; ㅎ;\n카카오는 위에서 얘기한 것과 같이 0/6문제 풀었구요. 네이버는 3/3 다 풀었습니다. 라인은 4/6문제 풀었는데 20~60초만 더 있었으면 냈는데 ㅠㅠㅠ 1자리대 초 남겨 놓고 제출하고 나서 보니 치명적인 실수가 ㅠㅠㅠㅠ 그후에 바로 고쳤는데 이미 끝\u0026hellip; 그때의 절망감이란 ㅎㅎㅎㅎㅎㅎ\n난이도 카카오 중상 네이버 하중 라인 중 난이도는 시간이랑 비례했다고 생각이 드네요. 문제 자체가 풀지 못할정도로 어려웠다기보다 시간내에 알고리즘을 구상하고 정리하고 최적화하는 것에 대해서 많이 요구 되었다고 생각이 들어요.\n결과 카카오는 당연히 떨어졌구요 ㅎㅎ. 라인도 최근에 결과를 이메일로 받았는데 떨어졌습니다. 라인은 아쉬움이 많이 남네요.\n","permalink":"https://blog.yoonho.site/2019-09-27-test-recruit-2019/","summary":"2019년 하반기 카카오(신입), 네이버(신입), 라인(인턴 전환)에서 정규직 채용 코딩 테스트를 봤습니다. 기업 기술 순서는 그저 테스트 시험일 순입니다. 코딩 테스트 경험이 없어서 긴장을 많이 했었습니다. 카카오의 경우 블라인드 채용이라 테스트를 먼저 봤고, 네이버와 라인은 서류가 먼저 있었습니다. 그렇지만 라인의","title":"2019 공채(카카오, 네이버, 라인) 코딩 테스트를 봤습니다"},{"content":"\nCreate a Meetup Account *지역 커뮤니티에서 마음에 드는 Meetup을 찾아 나와 같은 관심사를 가진 사람들을 만나보세요.*www.meetup.com\n자세한 내용은 링크를 확인해주세요!\n[AUSG Seminar Series] 2018 F/W 초보자를 위한 AWS 뿌시기\n지난 겨울에 성황리에 진행되었던 AUSG의 “초보자를 위한 AWS 뿌시기” 가 돌아왔습니다.\n2018 F/W 시즌을 맞이하여 더욱 다양하고 흥미있는 주제들로 준비하였습니다.\n1회차\nAUSG 고윤호님 Node.js 서버리스 프레임웍을 사용하여 싱글페이지 포트폴리오 제작하기 2회차 ~\n10월 개봉 \u0026lt;세부 내용\u0026gt; 주최 : AUSG (AWSKRUG 대학생 그룹) 내용 : Node.js 서버리스 프레임웍을 사용하여 싱글페이지 포트폴리오 제작하기 대상 : AWS를 활용한 개발을 배워보고 싶은 누구나 장소 : 서울특별시 강남구 논현로85길 46 GALA빌딩 메가존(주) B1 시간 : 9/19(수) 19:00 ~ 21:30 회비 : 10,000원 \u0026lt;기타 문의\u0026gt; Slack의 #ausg 채널 또는 ausg.awskrug@gmail.com을 통해 문의주세요. Slack의 AWSKRUG workspace에 가입 방법은 다음 링크를 참조해주시기 바랍니다. http://www.awskr.org/slack/\n","permalink":"https://blog.yoonho.site/2018-09-14-ausg-seminar-preparation/","summary":"Create a Meetup Account 지역 커뮤니티에서 마음에 드는 Meetup을 찾아 나와 같은 관심사를 가진 사람들을 만나보세요.www.meetup.com 자세한 내용은 링크를 확인해주세요! [AUSG Seminar Series] 2018 F/W 초보자를 위한 AWS 뿌시기 지난 겨울에 성황리에 진행되었던","title":"AUSG 세미나 발표 준비 중입니다"},{"content":"Nuxt 2.0에서 Typescript를 적용하는 방법에 대해서 한번에 요약되어 있는 글이 없어서 글로 정리하고 보일러플레이트로 repo를 만들어 뒀습니다.\n우선 vue-cli를 이용하여 nuxt starter-template을 받아줍니다.\nyarn global add @vue/cli @vue/cli-init vue init nuxt-community/starter-template \u0026lt;project-name\u0026gt; 그리고 기존에 있던 nuxt를 지우고 nuxt-edge(Nuxt.js 2.0)을 받아줍니다.\nyarn remove nuxt \u0026amp;\u0026amp; yarn add next-edge\n이것 자체로 nuxt-edge 설정은 완료되었습니다. 이제 Typescript를 설정을 해줍니다. Typescript와 nuxt에서 내부적으로 돌아가는 webpack을 위한 ts-loader 그리고 lint 적용을 위해서 tslint를 devDependencies에 설치해줍니다.\nyarn add typescript ts-loader tslint --dev\n설치가 완료되면 초기 설정 파일을 만들어줍니다. 아래 명령어를 실행하면 tsconfig.json과 tslint.json 파일이 각각 생성됩니다. tslint는 홈페이지를 참고해서 rule을 수정하시면 됩니다. *Gist 내용은 Copy\u0026amp;Paste 해주시면 됩니다.\ntsc --init \u0026amp;\u0026amp; tslint --init\n// tsconfig.json { \u0026#34;compilerOptions\u0026#34;: { /* Basic Options */ \u0026#34;target\u0026#34;: \u0026#34;es5\u0026#34; /* Specify ECMAScript target version: \u0026#39;ES3\u0026#39; (default), \u0026#39;ES5\u0026#39;, \u0026#39;ES2015\u0026#39;, \u0026#39;ES2016\u0026#39;, \u0026#39;ES2017\u0026#39;,\u0026#39;ES2018\u0026#39; or \u0026#39;ESNEXT\u0026#39;. */, \u0026#34;module\u0026#34;: \u0026#34;commonjs\u0026#34; /* Specify module code generation: \u0026#39;none\u0026#39;, \u0026#39;commonjs\u0026#39;, \u0026#39;amd\u0026#39;, \u0026#39;system\u0026#39;, \u0026#39;umd\u0026#39;, \u0026#39;es2015\u0026#39;, or \u0026#39;ESNext\u0026#39;. */, \u0026#34;allowJs\u0026#34;: true /* Allow javascript files to be compiled. */, \u0026#34;outDir\u0026#34;: \u0026#34;./.dist\u0026#34; /* Redirect output structure to the directory. */, /* Strict Type-Checking Options */ \u0026#34;strict\u0026#34;: true /* Enable all strict type-checking options. */, /* Module Resolution Options */ \u0026#34;moduleResolution\u0026#34;: \u0026#34;node\u0026#34; /* Specify module resolution strategy: \u0026#39;node\u0026#39; (Node.js) or \u0026#39;classic\u0026#39; (TypeScript pre-1.6). */, \u0026#34;baseUrl\u0026#34;: \u0026#34;./src\u0026#34; /* Base directory to resolve non-absolute module names. */, \u0026#34;paths\u0026#34;: { \u0026#34;*\u0026#34;: [\u0026#34;node_modules/*\u0026#34;], \u0026#34;~/*\u0026#34;: [\u0026#34;src/*\u0026#34;], \u0026#34;@/*\u0026#34;: [\u0026#34;types/*\u0026#34;] } /* A series of entries which re-map imports to lookup locations relative to the \u0026#39;baseUrl\u0026#39;. */, \u0026#34;esModuleInterop\u0026#34;: true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies \u0026#39;allowSyntheticDefaultImports\u0026#39;. */, /* Experimental Options */ \u0026#34;experimentalDecorators\u0026#34;: true /* Enables experimental support for ES7 decorators. */ } } 설정이 완료 되셨으면 Nuxt에서 typescript를 build 할 때 제대로 load 할 수 있도록 ts-loader를 연결해줍니다. *Gist 내용은 Copy\u0026amp;Paste 해주시면 됩니다.\n// nuxt.config.js module.exports = { srcDir: \u0026#34;src/\u0026#34;, extensions: [\u0026#34;js\u0026#34;, \u0026#34;ts\u0026#34;], /* ** Headers of the page */ head: { title: \u0026#34;portfolio\u0026#34;, meta: [ { charset: \u0026#34;utf-8\u0026#34; }, { name: \u0026#34;viewport\u0026#34;, content: \u0026#34;width=device-width, initial-scale=1\u0026#34; }, { hid: \u0026#34;description\u0026#34;, name: \u0026#34;description\u0026#34;, content: \u0026#34;my portfolio site\u0026#34; }, ], link: [{ rel: \u0026#34;icon\u0026#34;, type: \u0026#34;image/x-icon\u0026#34;, href: \u0026#34;/favicon.ico\u0026#34; }], }, /* ** Customize the progress bar color */ loading: { color: \u0026#34;#3B8070\u0026#34; }, /* ** Build configuration */ build: { /* ** Run ESLint on save */ extend(config, { isServer }) { const tsLoader = { loader: \u0026#34;ts-loader\u0026#34;, options: { appendTsSuffixTo: [/\\.vue$/], transpileOnly: true }, exclude: [/vendor/, /\\.nuxt/], } config.module.rules.push({ test: /((client|server)\\.js)|(\\.tsx?)$/, ...tsLoader, }) config.resolve.extensions.push(\u0026#34;.ts\u0026#34;) config.module.rules.map(rule =\u0026gt; { if (rule.loader === \u0026#34;vue-loader\u0026#34;) { rule.options.loaders = { ts: tsLoader } } return rule }) if (isServer) { config.externals = [] } }, }, } 마지막으로 vue에서 typescript를 쓸 때 다른 Component를 import할 수 있도록 .vue 파일 타입을 정의해줍니다. *Gist 내용은 Copy\u0026amp;Paste 해주시면 됩니다.\n// types/index.d.ts declare module \u0026#34;*.vue\u0026#34; { import Vue, { VueConstructor } from \u0026#34;vue\u0026#34; const vue: VueConstructor\u0026lt;Vue\u0026gt; export default vue } 선택가능한 부분 만약 class형태로 components를 나누신다면 nuxt-class-component와 nuxt-property-decorator를 참고하시기 바랍니다. 보일러플레이트에서는 적용 되었습니다. yarn add nuxt-property-decorator\n결론 이제 yarn dev를 실행하여 테스트 해보시기 바랍니다.\n","permalink":"https://blog.yoonho.site/2018-09-11-nuxt2-nuxt-edge-typescript/","summary":"Nuxt 2.0에서 Typescript를 적용하는 방법에 대해서 한번에 요약되어 있는 글이 없어서 글로 정리하고 보일러플레이트로 repo를 만들어 뒀습니다. 우선 vuecli를 이용하여 nuxt startertemplate을 받아줍니다. yarn global add @vue/cli @vue/cliinit vue init","title":"Nuxt 2.0(nuxt-edge) + Typescript"},{"content":" 이 글은 7월에 있었던 AWSKRUG Serverless 발표때 사용한 내용입니다.\n주의! 이 글은 삽질의 경험이 녹아든 글입니다. 필요하신 정보가 다 담겨있지 않을 수 있습니다.\n회사에서 PDF로 나온 교재를 이미지로 변환해야하는 일이 있었는데요. 시중에 있는 툴은 모두 한 페이지씩 변환하기 때문에 오래걸리더라구요. 한 페이지에 대략 10~15초 정도가 걸렸기 때문에 100 페이지 이상 이루어지는 교재의 경우 권당 15분 이상씩 걸리는 경우가 허다했습니다.\n(10+@)초 + N페이지 = 파일당 변환 시간\n파일당 변환시간 + 변환 요청 파일 수\n특히 나중에 도입될 변환 서비스에서 너무 과한 시간이 걸릴 것으로 판단해서 병렬처리를 도입하려고 하였습니다. 그런데 PC에서 병렬처리는 한계가 있기 때문에 AWS Lambda를 이용하기로 결정하였습니다.\n1. 고민들 작업을 시작하기 전에 했던 고민들이 있었는데요. 첫번째는 어떤 Program Language를 사용할까 하는 것이었습니다. Lambda에서 실행할 것이었기 때문에 Lambda에서 운영되는 언어중에 골랐어야 했습니다.\n후보로 있었던 언어는\n파이썬 Javascript Java C# 제가 파이썬을 자주 사용하고 오랫동안 좋아하는 언어였기 때문에 처음엔 파이썬을 사용하려고 했습니다. 그런데 회사에서 작업을 Node.js로 구성하고 있고 요즘 작업 대부분을 Node.js 환경에서 하다보니 Node.js로 시작하는게 좋겠다 싶어서 Javascript로 처음엔 시작했습니다.\n2. 삽을 들다 Javascript에서 PDF 렌더링을 Mozilla에서 만든 pdf.js를 이용했습니다. 이 pdf.js는 canvas에 의존적인데요. node에서는 canvas가 없기 때문에 canvas-node 를 설치해야합니다. Lambda에서 설치하기 위한 방법은 이 가이드에 잘 나와있습니다. canvas-node의 경우 Binary file로 되어있습니다. Lambda에 사용자 환경을 구성하기 위해서는 EC2에서 AMI(Amazon Machine Image) 환경을 구성하고 Lambda로 배포해야합니다. 그래서 가이드에 나온대로 진행하고 예제 소스를 사용했습니다. Lambda에서 작동해야하기 때문에 Local환경에서는 테스트하지 않고 바로 Lambda에 소스를 올렸습니다.\n/** * 이 예제는 가이드에 나와있는 것과 동일한 예제입니다. * 저는 이 소스를 serverless framework 환경에 맞춰서 수정하였습니다. */ let {createCanvas} = require(\u0026#34;canvas\u0026#34;); ​ function hello(event, context, callback) { let canvas = createCanvas(200, 200), ctx = canvas.getContext(\u0026#39;2d\u0026#39;); ​ // Write \u0026#34;Awesome!\u0026#34; ctx.font = \u0026#39;30px Impact\u0026#39;; ctx.rotate(0.1); ctx.fillText(\u0026#39;Awesome!\u0026#39;, 50, 100); ​ // Draw line under text let text = ctx.measureText(\u0026#39;Awesome!\u0026#39;); ctx.strokeStyle = \u0026#39;rgba(0,0,0,0.5)\u0026#39;; ctx.beginPath(); ctx.lineTo(50, 102); ctx.lineTo(50 + text.width, 102); ctx.stroke(); ​ callback(null, \u0026#39;\u0026lt;img src=\u0026#34;\u0026#39; + canvas.toDataURL() + \u0026#39;\u0026#34; /\u0026gt;\u0026#39;); } ​ module.exports = {hello}; 예제는 잘 실행되었습니다. 변환속도도 괜찮고 맘에 들었습니다. 이거면 되겠다 싶어서 소스를 수정하기 시작했습니다. 예제를 조금 수정해서 한글 텍스트를 써서 작성하고 실행했습니다. 그런데 그때 예상치 못한 문제를 만났습니다.\n3. 예상치 못한 문제를 만나다 테스트용 소스는 충격적이게도 한글 텍스트를 제대로 인식하지 못하고 글자가 깨져서 안나왔습니다. 문제를 해결해보려고 여러 방법을 시도해봤는데요.\n인코딩 문제 한글 폰트 문제 시스템 언어 문제 먼저, 인코딩 문제의 경우 EUC-KR(윈도우에서의 한글 인코딩), UTF-8 등 한글 지원 인코딩을 적용해봐도 해결되지 않았습니다. 그래서 두번째로 한글 폰트 문제를 해결해보려고 오랜시간 삽질 끝에 한글 폰트를 넣고 실행해봤습니다만 문제는 마찬가지였습니다. 제가 모르는 방법으로 해결 방법이 있었겠지만 저는 그 방법을 찾지 못했습니다. 결국 오랜시간의 삽질에도 불구하고 그래서 과감하게 미련없이 다른 언어의 다른 방법으로 환승했습니다.\n4. 도와줘요 Adobe! 결국, 다른 남은 언어 중에서 Python, Java의 선택지를 생각하면서 알아보다가 Python에서 PDF Rendering Library 중 유명한 것이 Poppler입니다. 그런데 이 라이브러리도 Bynary file에 의존적이었습니다. 반면에 Java에서 사용하는 라이브러리인 PDFbox는 Adobe에서 Adobe Reader를 만들때 사용한 동일한 라이브러입니다. 이 라이브러리는 OS에 최적화된 파일에 의존하지 않고 Java의 JVM 바이트 코드에서 작동하는 라이브러리만으로 구성되어 있었기 때문에 PC에서 컴파일하여 배포하면 끝나는 형태였습니다. 이미 AMI를 통해 배포하는 것에 굉~장한 귀찮음을 느끼고 있었기 때문에 저는 바로 Java로 작업을 시작하였습니다.\nAdobe에서 오픈소스로 제공하는 이 PDFbox라는 라이브러리는 Adobe Reader 프로그램에서 사용하는만큼 Adobe Reader에서 정상적으로 작동하면 이 라이브러리를 사용했을 때도 작동해야 한다고 하는 문구가 매우 설득력 있었습니다.\n그래서 새로운 삽을 들었습니다. Repository를 만들고 Serverless framework에서 Gradle 기반 Java Template로 프로젝트를 만들었습니다. Gradle을 통해서 PDFbox를 받고 Main Class에서 PDFbox를 load 하고 Lambda 이벤트를 받으면 이벤트에 있는 S3 주소를 받아서 그 위치에 변환된 Image 파일을 저장하도록 만들고 첫 페이지를 변환했습니다. 중간에 여러번의 삽질이 있었지만 결국 성공했습니다. 영문 페이지도 한글 페이지도 성공적으로 변환되었습니다. 이미지 등도 잘 변환되었구요. 이때 엄청 환호성을 질렀습니다. 글로는 간략하게 설명됬었지만 2~3일 정도 고생했거든요.\n5. 병렬처리 시작 꽤 오랜시간 고생했지만 아직 본래 하려던 내용은 시작도 못했습니다. 애초에 목적은 변환이 아니라 병렬처리였으니까요. 그래서 소스를 병렬로 처리하기 위해서 작업을 시작했습니다. 병렬로 변환하게 만드는 소스를 짜기까지는 오래 걸리지 않았습니다. 애초에 잘 작동하는 소스로 Lambda를 비동기로 병렬 Invoke하고 취합해서 저장하고 결과를 돌려주면 되었으니까요.\nLambda의 함수 내에서 분기를 만들어줬습니다. 큰 의미없이 함수를 여러개 만드는건 관리도 불편하더라구요. 함수를 만들때 S3 Event가 발생할 것도 고려하여 작성했습니다. 특정 경로는 자동 변환되고 User마다 올리는 변환에는 수동으로 실행하도록 하였습니다.(다 되었는지 확인하는 Response가 있기 때문에)\nLambda FlowGraph\nrecievePage3EvnetTrigger FlowChart\n6. 결과와 문제점 자, 이제 프로그램은 완성되었습니다. 길고 긴 시간이 걸렸습니다만 소스는 무사히 완성되었네요. 실행방법은 두가지입니다.\nS3에 이벤트가 발생할수 있는 경로에 PDF파일을 업로드 S3에 PDF파일을 업로드하고 Lambda를 Invoke 변환되어 저장된 페이지의 이미지 파일 이름을 알아야하기 때문에 저는 페이지별로 경로를 모은 index 정보가 담긴 json파일도 저장했습니다. 애초에 파일당 수십분씩 걸리던 PDF 변환이 30초 안에 끝나는 마법을 보면서 혼자 피식피식 했습니다. 하지만 사용하면서 몇가지 문제점도 있었는데요.\n람다 동시성 예약 1000건 특수한 글자 인식 오류 시도해보면 좋았을 것들 Python AWS SQS(Simple Queue Service) 엄격한 권한 관리 7. Demo 이 Repository에서 해당 소스를 가져올수 있습니다. 맘에 드신다면 별⭐️도 췍췍!\n","permalink":"https://blog.yoonho.site/2018-09-05-aws-lambda-parallel-processing-pdf-image-conversion/","summary":"이 글은 7월에 있었던 AWSKRUG Serverless 발표때 사용한 내용입니다. 주의! 이 글은 삽질의 경험이 녹아든 글입니다. 필요하신 정보가 다 담겨있지 않을 수 있습니다. 회사에서 PDF로 나온 교재를 이미지로 변환해야하는 일이 있었는데요. 시중에 있는 툴은 모두 한 페이지씩 변환하기 때문에 오래걸리더라구요.","title":"AWS Lambda 병렬 처리를 통한 PDF to Image 변환 삽질기"},{"content":"조금 된 소식이지만 AUSG(AWSKRUG University Student Group) 2기 활동을 하게 되었습니다. 처음엔 지원을 할까 말까도 굉장히 고민했습니다만 다행히도 대부분의 고민이 해결되었습니다. 아직 많은 사람들과 얘기 해보지는 못했지만 벌써 재밌고 다양한 사람들을 만난 것 같구요. 재밌는 세션도 많이 볼수 있을거 같아서 기대됩니다 ㅎ\n활동목표 AUSG 멤버들의 AWS학습을 위한 교육세션 전파를 위한 세미나 주최 외부 대학생 대상 교육 AWS, AWSKRUG의 공식 행사 서포트 Slack #university 모임 운영 링크 Slack AWSKRUG Homepage(리뉴얼 예정) Facebook Group ","permalink":"https://blog.yoonho.site/2018-09-05-ausg-2th/","summary":"조금 된 소식이지만 AUSG(AWSKRUG University Student Group) 2기 활동을 하게 되었습니다. 처음엔 지원을 할까 말까도 굉장히 고민했습니다만 다행히도 대부분의 고민이 해결되었습니다. 아직 많은 사람들과 얘기 해보지는 못했지만 벌써 재밌고 다양한 사람들을 만난 것 같구요. 재밌는 세션도 많이","title":"AUSG 2기로 활동하게 됐습니다."},{"content":"시간이 좀처럼 안나서 뜸뜸이 번역하고 있어서 나온지 꽤 됬는데도 아직 포스팅을 못했습니다😂 그래서 좀 부족하더라도 미리 올려 놓고 조금씩 수정하려구요. 양해를 부탁드립니다.\n얼마전에 메일로 Now를 만드는 회사인 Zeit에서 새소식이 왔습니다. 바로! Serverless docker beta!!!!(띠용🤔) 서버리스면 서버리스고 도커면 도커지 두개가 같이 있을 수 있나…??!!!!!! 도커가 서버리스로?! 아무튼 그래서 번역을 해보았습니다. 실제 사용 후기는 이후에 올려드리겠습니다. 오역이나 어설픈 부분은 알려주시기 바랍니다😄(도와줘서 고마워요 구글 번역기)\n올해 ZEIT Day Keynote의 초점은 Now 클라우드 플랫폼의 새로운 가능성입니다. 특히, 우리는 Serverless Docker 개발에서 우리의 초점을 강조했습니다.\n오늘, 우리는 공개 베타 버전으로써 발표할 것입니다. 다음 기능을 제공합니다:\n1.5백만개의 배포 데이터를 기반으로한 콜드 부팅 성능가 10~20배 개선\n- 대부분의 작업부하에서 1초 미만의 콜드 부팅(전체 왕복)으로 변환됩니다.\n- A new slot configuration property which defines the resource allocation in terms of CPU and Memory, defaulting to c.125-m512 (.125 of a vCPU and 512MB of memory) 이를 통해 응용 프로그램을 가장 적합한 제약 조건에 맞추고 특수 CPU 기능, GPU 코어 등에 길을 열어두었습니다.(paving the road가 관용어인거 같은데 길을 열어두다, 가능성을 열다라는 뜻인거 같아요) 엄격하게 지정된 가변 제한\n- 최대 실행 시간 (기본값은 5 분, 최대 30 분)\n- 마지막 요청 후 종료 시간 초과 (기본값은 1 분, 최대 5)\n- 자동 스케일링 전에 최대 요청 동시성(기본값 10) 배포에 대한 HTTP/2.0과 WebSocket의 연결을 지원\n- 당신의 어플리케이션을 다시 function으로 작성할 필요가 없습니다. 다만, 계속 그것을 사용할 수 있습니다. Automatic port discovery. We no longer rely on the EXPOSE instruction. We automatically forward traffic to the port of the process started by CMD Read on to learn how it works or head directly to our examples.\n실습 방법 Serverless Node.js Functions micro를 이용해 간단한 HTTP 서비스 함수를 배포 해봅시다:\nnpm ci로 빌드된 node-function.now.sh을 통해 액세스 할 수 있는 간단한 function입니다.\n여기서 일어나는 일들입니다:\n클라우드와는 다른 우리의 로컬 파일 시스템 배포가 만들어집니다. A simple Dockerfile is used to hold the instructions to build the project 간단한 Dockerfile은 프로젝트 빌드 지침을 보관하기 위해 사용됩니다. Node.js version(10)과 package manager(npm ci)의 자체 설정으로 빌드합니다. index.js 파일은 메인 함수가 들어가있습니다. 이 serverless container는 125CPUs와 512MB 메모리로 제한됩니다. DNS 조회+ TLS handshake + Cold Boot + 전체왕복까지 일어나는데 600ms~입니다. Once the deployment instance is warm, subsequent requests take 100ms~ 일단 배포 인스턴스가 가동되었다면, 이후 요청은 100ms~입니다. 이 작업을 수행하기 위한 요구사항은 오직 당신의 now.json에서 기능 플래그를 통해 베타를 활성화 하는 것입니다:\nServerless Go + Websockets 이 기술의 능력을 조금 더 깊숙히 알아봅시다. 다음 예제는 Docker registry에서 Go로 작성된 이미지를 가져옵니다.\nHTTP/2.0과 웹소켓을 사용하는 Serverless shell은 terminal.now.sh에서 사용가능합니다.\n이 데모의 주요사항:\n공개 Docker registry에서 변경되지 않은 Dockerfile 사용 다른 프로그래밍 언어와 런타임: Go 파일 시스템을 검사할 수 있는 우리의 능력으로 입증된 일시적인 상태 유지 - 5분(기본시간) 이후, 상태는 재활용됩니다. 500ms 미만의 Cold 왕복. Go는 거대한 어플리케이션이지만 더 나은 시작 성능을 보여줍니다.(이 예제에서는 일반적으로 400~500ms) 이 서비스는 초기화된 HTML를 제공하는 HTTP 요청에 응답합니다. 그리고 WebSocket 연결을 통해 PTY 데이터를 교환합니다. Serverless Rust(Global) 이 인프라는 Global Now와 합쳐져 매우 잘 작동합니다. 다시 말해, 모든 Global locations에 serverless하게 배포하는데 하나의 플래그만 있으면 됩니다.\n여기 Rust + Hyper 배포 예제가 있습니다:\nrust-http-microservice-v2.now.sh, 모든 지역에서 즉시 사용할 수 있는 Rust 마이크로서비스\n이것은 나머지 예제들과 비슷하지만, 우리는 now --regions all을 실행하는 것으로 처음부터 모든 지역에 바로 확장되었습니다.\n이것은 또한 다음을 실행하여 이미 배포된 후에도 확장할 수 있습니다:\nAutomatic Horizontal Scalability(자동 수평 확장성) (정의하는 경계 안에서)당신이 정의한 파라매터로 자동 확장하는 이 시스템의 능력을 강조하기 위해서, 여기 wrk(load-testing tool)로 [stress test](https://ko.wikipedia.org/wiki/ì¤í¸ë ì¤_íì¤í¸)를 위한 예제가 있습니다.\n즉각적이고 예측 가능한 수평적 확장성\n이 것은(우리 생각에) Serverless 배포의 가장 중요한 특징을 정의합니다. 하지만, 우리가 다음을 보게 되는 것만은 아닙니다.(\u0026gt; 무슨말이죠..?)\nServerless 컴퓨팅의 원리 We selected these demos in particular to underline a very important point. We think Serverless can be a very general computing model. One that does not require new protocols, new APIs and can support every programming language and framework without large rewrites.\nHere are three of the underlying ideas behind this new architecture.\n1. Focus on Code, Not Infrastructure Serverless enables engineers to focus on code rather than managing servers, VMs, registries, clusters, load balancers, availability zones, and so on.\nThis, in turn, allows you to define your engineering workflow solely around source control and its associated tools (like pull requests). Our recent GitHub integration, therefore, makes it possible to deploy a Docker container in the cloud solely by creating a Dockerfile.\nIt is not sufficient to ignore that the infrastructure is there, or forget about it. The execution model must make it so that manual intervention, inspection, replication, and monitoring or alert-based uptime assurance is completely unnecessary, which takes us to our next two points.\nWhat Are the Benefits?\nWhen we deployed the examples above, we didn’t have to deal with:\nClusters or federations of clusters Build nodes or build farms Container registries and authentication Container image storage, garbage collection and distributed caching 2. Deployments Should Self-Heal A very common category of failure of software applications is associated with failures that occur after programs get into states that the developers didn’t anticipate, usually arising after many cycles.\nIn other words, programs can fail unexpectedly from accumulating state over a long lifespan of operation. Perhaps the most common example of this is a memory leak: the unanticipated growth of irreclaimable memory that ultimately concludes in a faulty application.\nServerless means never having to “try turning it off and back on again”\nServerless models completely remove this category of issues, ensuring that no request goes unserviced during the recycling, upgrading or scaling of an application, even when it encounters runtime errors.\nHow Does Now Ensure This?\nYour deployment instances are constantly recycling and rotating. Because of the request-driven nature of scheduling execution, combined with limits such as maximum execution length, you avoid many common operational errors completely.\n3. Deployments Should Automatically and Predictably Scale Perhaps the most important or appealing aspect of the serverless paradigm is the promise of automatic scalability.\nIn its most basic form, a function automatically scales with a 1:1 mapping of requests to resource allocations. A request comes in, a new function is provisioned or an existing one is re-used.\nWe have taken this a step further, by allowing you to customize the concurrency your process can handle.\nTechnical Details This new infrastructure is already available to Docker deployments made in the free tier, or for paying subscriptions that opt-into the feature via now.json:\nPlease ensure that your Now CLI is up to date, or deploy directly via our GitHub integration or API.\nLimits Hard Limits\nThese limits are fixed. They are subject to change once the feature goes into General Availability.\nA maximum of 3 concurrent deployment instances for OSS A maximum of 10 concurrent deployment instances per subscription A maximum of 500 concurrent requests/connections across deployments per subscription Soft Limits\nThese limits are configurable in now.json as part of a limits object.\nmaxConcurrentReqs max concurrency of each process (min 1, max 256, default 10) duration max amount of time in ms your process can run (min/default 5 minutes, max 30 minutes) timeout how long in ms to wait after the last request to downscale (min/default 1 minute, max 30 minutes) Pricing While in beta, we require a paid subscription to be able to go over the maximum of 3 concurrent deployment instances. Current rates apply and are subject to change.\nNext up: Faster, More Capable, Smaller Faster Cold Start Despite having so dramatically sped up instantiation times, we still have very significant room for improvement.\nWe are excited about unveiling some of these over the coming weeks before the new infrastructure goes into General Availability.\nAdditional slot Configurations We will introduce new slot identifiers so that you can fit your applications into other CPU/memory combinations.\nThis is important for resource-intensive applications.\nSmaller Images When your code is built, we post-process the resulting snapshot and let you know what the total size is.\nWe are confident that in its present form, our system can fit the vast majority of our customers’ workloads without any issues.\nHowever, we are currently developing improvements to optimize this dimension further, without you having to make any changes.\n결론 이 베타 버전은 지난 2년동안 수백만 건의 배포를 완료한 대규모 배포와 다양한 사용자 기반의 교훈과 경험이 포함되어 있습니다.\n시작하기 위해서, 이 릴리즈에서 함께 제공한 종합 예제 목록을 참고하시는 것을 제안합니다.\n이후 몇 주 동안, 우리는 새로운 제품에 대한 더 자세한 기사와 문서를 공유 할 것입니다.\n이 기간 동안 당신의 의견은 중요합니다. 제발 저희에게 얼마나 잘 작동하는지 알려주세요.\n","permalink":"https://blog.yoonho.site/2018-09-02-serverless-docker-beta-zeit/","summary":"시간이 좀처럼 안나서 뜸뜸이 번역하고 있어서 나온지 꽤 됬는데도 아직 포스팅을 못했습니다😂 그래서 좀 부족하더라도 미리 올려 놓고 조금씩 수정하려구요. 양해를 부탁드립니다. 얼마전에 메일로 Now를 만드는 회사인 Zeit에서 새소식이 왔습니다. 바로! Serverless docker beta !!!!(띠용🤔) 서버리스면","title":"(번역 중)Serverless Docker Beta"},{"content":"제가 학교에 재학 중일 때는 개인적으로 파이썬을 자주 쓰기도 하고 프로젝트에서도 머신러닝이나 데이터 분석때 파이썬을 자주 쓰다보니 패키지 관리를 위해서나 호환성을 위해서나 아나콘다를 설치해서 쓰는 일이 잦았습니다.\n그런데 회사에서 일을 할때는 주로 Node.js를 쓰고 있어서 최근 파이썬을 사용하는 일이 전무했습니다. 언젠간 쓰겠거니 싶어서 여태 신경 안쓰고 놔두고 있었는데 요즘 용량에 허덕이면서(128GB… 하핫) 과감히 삭제를 결심했습니다.\n몇가지 글을 찾아보면서 삭제 방법을 찾아봤는데요. 앱을 이용하여 삭제하는 것과 수동으로 삭제 하는 방법 두가지를 소개합니다. 제일 정확한 방법은 아닐지 모르겠습니다만 찾아본 방법 중에 제일 단순하더군요.(사실 맥 사용 기간이 얼마 안된 것도 있습니다…)\nApp Cleaner 앱스토어에서 “App Cleaner”라는 앱을 받으면 Anaconda Navigator.app을 삭제할 수 있습니다. 이때 관련된 아나콘다 패키지들도 다 찾아주더라구요. 총 4.5GB의 결과물을 찾을 수 있었습니다. 개인적으로는 AppDelete보다 좋았습니다.(무료기도 하구요 ㅎ)\n직접 삭제 두번째 방법은 일일이 해당 경로를 삭제하는 것입니다. 위에 나타난 경로 그대로 삭제하면 될 것 같네요. 불안하시면 앱을 이용해주세요 ㅎㅎㅎ\n$ rm -rf ~/anaconda3 ~/.conda ~/.anaconda ~/.condarc $ rm ~/Library/Application Support/binstar/*anaconda* $ rm ~/Library/Receipts/io.continuum.pkg.anaconda* 잘못된 내용이 있으면 댓글↓↓↓ 달아주세요😃\n참고 링크입니다.\nUninstall Anaconda on a Mac - Full Removal Guide ‎Mac App Store에서 제공하는 Cleaner-App ","permalink":"https://blog.yoonho.site/2018-08-19-anaconda-uninstall-macos/","summary":"제가 학교에 재학 중일 때는 개인적으로 파이썬을 자주 쓰기도 하고 프로젝트에서도 머신러닝이나 데이터 분석때 파이썬을 자주 쓰다보니 패키지 관리를 위해서나 호환성을 위해서나 아나콘다를 설치해서 쓰는 일이 잦았습니다. 그런데 회사에서 일을 할때는 주로 Node.js를 쓰고 있어서 최근 파이썬을 사용하는 일이 전무했습니다.","title":"Anaconda Uninstall on macOS"},{"content":"개발 블로그를 시작해야지 생각하면서 고려했던 블로그 플랫폼이 많이 있었습니다.\nMedium tumblr Ghost GitHub pages + Jekyll(or Hexo or Hugo or Ghost) 등등등… 아무래도 개발자다보니 GitHub + Jekyll로 가려고 계속 시도를 했습니다. 그치만 어느 순간 글을 쓰는 것보다도 디자인에 계속 더 신경을 쓰고 있더군요. 아무래도 주객이 전도 바뀌었다 싶어서 여러 글을 찾아보다가 PIGNOSE님의 글을 참고해서 텀블러도 사용해봤습니다. 텀블러 무료 테마가 제가 바라던게 무료로 없었고, 만들자니 학습곡선이 가파르고(하하;;) 그래서 이리돌고 저리돌다가 결국 미디엄에 비상 착륙했습니다.\n미디엄이 제가 원하는 테마를 갖췄는지는 아직 모르겠습니다. 그렇지만 결국 제가 테마를 원했던 이유는 가독성과 깔끔한 디자인, 쓰기 편한 부분, 이후 이사 가기가 편해야 하는점 등을 고려했을 때 합격점에 들어서있는 플랫폼이라고 생각했습니다.\n결국 만족스러운 답을 아직 만나지는 못했습니다. 그치만 일단 블로그를 시작할 수 있게 되었다는 점에서 나중에 옮기더라도 아무것도 안적는 것보다 나은 것 같네요! 여러분도 블로그를 고민하신다면 무엇을 고민하시더라도 목적이 있으실텐데 그건 80% 이상 글을 ‘쓰기’ 위함이실텐데 저처럼 여기저기 방황하다가 목적을 잃지 마시고 저랑 같이 시작부터 하시죠! 😄\n그럼 오늘은 이만 총총…3\n고민했던 흔적들의 수많은 링크들 중\nhttps://themeisle.com/blog/wordpress-vs-ghost-vs-medium/ ","permalink":"https://blog.yoonho.site/2018-08-17-ghost/","summary":"개발 블로그를 시작해야지 생각하면서 고려했던 블로그 플랫폼이 많이 있었습니다. Medium tumblr Ghost GitHub pages + Jekyll(or Hexo or Hugo or Ghost) 등등등… 아무래도 개발자다보니 GitHub + Jekyll로 가려고 계속 시도를 했습니다. 그치만 어느 순간 글을 쓰는","title":"언젠가 Ghost로 옮기길 바라며…"},{"content":"(옮긴글…)\n7월 12일 AWS Serverless 모임 때 발표를 준비하는데 AWS에서 서비스하는 Lambda와 S3를 이용하여 PDF파일을 Image파일로 변환했던 방법을 소개하려고 합니다.\nmeetup에서 참여신청할수 있습니다.\n","permalink":"https://blog.yoonho.site/2018-08-15-aws-ready-presentation/","summary":"(옮긴글…) 7월 12일 AWS Serverless 모임 때 발표를 준비하는데 AWS에서 서비스하는 Lambda와 S3를 이용하여 PDF파일을 Image파일로 변환했던 방법을 소개하려고 합니다. meetup 에서 참여신청할수 있습니다.","title":"발표 준비 중..."},{"content":"블로그를 운영하는데 있어서 가장 기본이 되는 것이 무엇인가 많이 생각해봤습니다. 제 생각에는 아무래도 구독자가 가장 읽기 편한 환경을 만드는 것이라고 생각했습니다. 좋은 글도 읽히지 않으면 기억에 남기 힘들고 읽기도 힘들기 때문이죠. 저는 그런 블로그들에서 벗어나야한다고 생각했습니다.\n앞으로 꾸준히 포스트를 올리기 위해서 노력하겠지만 글을 쓴다는게 매번 쉬운 일은 아니더군요. 그래서 짧은 글들도 자주 올라올거라고 생각합니다. 제 글이 여러분에게 도움이 될 수 있기를 바랍니다. 오늘은 여기까지.\n","permalink":"https://blog.yoonho.site/2018-08-15-starting-blog/","summary":"블로그를 운영하는데 있어서 가장 기본이 되는 것이 무엇인가 많이 생각해봤습니다. 제 생각에는 아무래도 구독자가 가장 읽기 편한 환경을 만드는 것이라고 생각했습니다. 좋은 글도 읽히지 않으면 기억에 남기 힘들고 읽기도 힘들기 때문이죠. 저는 그런 블로그들에서 벗어나야한다고 생각했습니다. 앞으로 꾸준히 포스트를 올리기","title":"블로그를 시작해도 될까요?"}]