블로그 프로젝트를 위해 학습하며 작성한 메모Zettel들
나는 학습을 위한 방법론으로 Zettelkasten을 쓴다.
오늘은 한번 재미로 블로그를 개발하면서 얼마나 배웠는지 알아보려고 블로그 프로젝트와 관련되어 작성한 메모Zettel들을 분류해 보았다.
Zettel
Zettel은 하나 하나가 일정 분량의 메모로, 링크를 통해 서로 연결될 수 있다.
- 제목은 메모의 내용을 한 문장으로 요약한 것이다.
- 메모의 내용은 (각주를 제외하고) 대충 모니터를 9등분 했을 때 한 칸에 들어갈 정도의 분량이다. (더 길거나 짧을 수도 있다)
- 이걸 전부 외웠다는 게 아니라, 일종의 컨닝 페이퍼다. 시험 칠 것도 아니니까 필요하면 (obsidian 검색 등으로) 찾아서 보면 된다.
- 나는 볼 수 있지만 너네는 못 본다.
예시
예를 들면 이렇다. (링크는 다른 메모Zettel와 연결되는데, 이 블로그에선 전부 404가 나온다. 너네는 못본다니까?)
kur2204212221.HTTP 메시지 형식과 내용
HTTP 메시지는 Request와 Response로 나뉘어진다. 그러나 두 메시지의 형식은 동일하고 내용만이 다르다.
req, resp 둘 다
하나의 start-line
,0개 이상의 header line
, 헤더 필드의 끝을 의미하는빈 라인
,Body(optional)
로 이루어진다. 각 line은CRLF
로 구분된다.
start-line header-field-name: field-value ... header-field-name: field-value Body(optional)
start-line은 request-line과 status-line으로 나뉜다. 형식은 공백(SP)으로 분할되는 3가지로 동일하나 내용이 다르다.
req: METHOD URL HTTPversion
res: HTTPver status-code reason-phrase
여기서 request-line의 METHOD(GET POST HEAD ...)와 response-line의 status-code(1xx 2xx ... 5xx)는 HTTP 스펙에 정의되어 있다.
참고:
kur1649761332.book.컴퓨터 네트워크 하향식 7판 and 8E
RFC1945(HTTP/1.0), RFC2616(HTTP/1.1)
저건 좀 긴 편이고 짧은 것도 몇개 올려 보자
kur2206270714.CommonMark는 표준적이고 모호하지 않은 Markdown마크다운 스펙이다
마크다운은 원래 John Gruber가 스펙과 함께 구현체를 공개한 가벼운 마크업 언어이다. 하지만 스펙은 모호하고[1], 구현체는 버그가 많았다. 더 심각한 건 md가 핫해지면서 구현체가 난립했는데, 위 두 이유로 인해 구현체 간 불일치가 상당했다[2].
CommonMark는 이 모든 문제를 해결하기 위해, 마크다운의 모호하지 않은 스펙과 그에 대응하는 테스트 케이스, 레퍼런스 구현체를 제공한다.
[1] kur2206280935.마크다운의 최초 개발자는 확장성을 위해 md 스펙을 모호하게 정의했다
[2] https://commonmark.org/#why
kur2301270854.비대칭 키 암호화는 공개키를 공개하는 주체가 실제 공개키 발급자인지 보증할 수 없어 중간자 공격에 취약하다
비대칭 암호화 방식은 비밀키와 공개키의 수학적 관계를 이용하여 암호화와 복호화를 보장한다. 그러나 공개키를 공개하는 주체가 실제 공개키를 발행한 주체인지는 보증할 수 없다. 그러므로 비대칭 암호화만으로는 중간자 공격(man-in-the-middle)[1]에 대응할 수 없다[2].
예를 들어 피싱 사이트X가 공개키Pa를 공개하면서 발급자A인척 하면, 클라이언트C는 피싱 사이트X에 방문하여 (공개키Pa로 암호화한) 민감한 정보f(Pa,c)를 넘겨줄 수 있다. 이는 비대칭 암호화만으로는 회피할 수 없는 공격이다
[1] https://en.wikipedia.org/wiki/Man-in-the-middle_attack
[2] https://en.wikipedia.org/wiki/Certificate_authority#Overview
kur2208232142.명백하고 자명하기 어렵다면 최소한 추가 설명이나 메뉴얼 없이 이해하고 사용할 수 있어야 한다
kur2208232100.웹 페이지는 what, where, how가 자명해야 사용자가 고민하지 않는다. 하지만 항상 자명할 수는 없다. 근본적으로 복잡한 작업이나 특별하고 독창적인 작업이라면 명백하게 만들기 어렵다.
이럴 때는 최소한 추가 설명이나 메뉴얼 없이 이해하고 사용할 수 있어야 한다[1].[1] kur2208201118.book.사용자를 생각하게 하지마18
아래는 블로그 프로젝트와 관련된 zettel을 모두 다 나열해 본 것이다.
대충 이런게 하나 둘... 140개나 있네? ㅋㅋ
일반
kur2204011005.개발 도중에도 문제에 대한 학습을 지속해야 한다
kur2204130855.공식 문서를 읽어라 Read the Official Doc
Rationale
kur2204241150.블로깅(블로그 blog)을 하는 이유
kur2204241217.블로그를 바닥부터 직접 만드는 이유는 데이터 직접 관리와 학습 때문
kur2204251545.블로그의 사용자 분류(작가, 독자, 개발자)와 사용하는 기능(usecase)들
kur2204261339.질 좋고 오래 가는 블로그의 핵심은 작가의 내적 동기다
kur2204261350.운영하고 싶은 이상적인 블로그의 특징
kur2204262029.이미 있는 블로그 시스템을 쓰지 않는 이유
AWS
kur2203242131.AWS 사용 전 준비 - 관리자 IAM 유저 생성
kur2204081712.AWS IAM 유저로 Billing 정보 보기
Internet
Port and Ping
kur2204092034.Ping의 정체와 사용
kur2204101401.port는 프로세스 하나가 독점하는분류 1,5 제목x 1,1. id , 컴퓨터 네트워크의 가상적 연결점이다
kur2204101419.port를 열고 닫는 주체는 어플리케이션이다
kur2204121539.리눅스에서 port 사용 현황 확인하는 법
Structure of the Internet
kur2204152129.인터넷은 네트워크들의 네트워크(network of networks)다
kur2204151113.ISP들은 계층 구조를 이루며 서로 연결되어 있다
kur2204151124.ISP(Internet Servicw Provider)는 인터넷 서비스를 제공하는 기관이다
kur2204151524.end system 혹은 host는 인터넷에 연결된 말단 기기이다
kur2204151533.end system과 access network를 합쳐 network edge라 부른다
kur2204151548.access network는 end system을 라우팅 경로 상 첫번째 라우터에 연결하는 네트워크이다
kur2204152158.end system에 인터넷을 제공하는 기관도 ISP다
kur2204171406.현대 인터넷의 구조
Layered Protocols and Packet Switching Network
kur2204151509.protocol은 둘 이상의 통신 개체 간 메시지 형식 뿐 아니라 송수신 등의 이벤트 대응 방법까지 정의한다
kur2204160734.패킷 교환은 회선 교환보다 효율적이며 인터넷과 최근 통신의 대세이다
kur2204160919.라우팅 개괄 Routing summary
kur2204160952.패킷 스위칭 네트워크의 성능 - delay, packet loss, throughput
kur2204171500.인터넷 5계층 프로토콜 스택 Internet 5 layers protocol stack
kur2204181550.계층 구조의 서비스 모델 service model of Layered architecture
kur2204181613.TCP는 UDP와 달리 연결지향적이며 Reliable data 전송, 혼잡 제어를 한다
kur2204182128.Application이 이용 가능한 Transport 서비스 네 가지
kur2204182202.Socket은 Application 계층과 Transport 계층 사이의 인터페이스다
Web
HTTP
kur2204212158.HTTP는 request(c to s)와, response(s to c)를 어떻게 보낼지 정의하는 stateless protocol이다
kur2204212221.HTTP 메시지 형식과 내용
Web page
kur2204190651.웹 페이지는 URL로 참조 가능한 객체(a file)들로 이루어 진다
kur2206222227.Data URL을 통해 데이터를 문자열로 인코딩하여 html 페이지에 삽입할 수 있다
kur2206230832.크롬 66부터 음소거 muted 되지 않은 비디오, 오디오의 자동재생 autoplay는 불가능하다
kur2206230838.브라우저는 HTML에 있는 상대-절대 URL의 생략된 부분을 적절히 채워 서버로 request한다
Domain
kur2206252030.도메인 네임에 하이픈hyphen(-)을 넣지 않는 것이 일반적이다
kur2206252120.도메인 구매 사이트 평가 기준과 해외 업체 비교 사이트 tld-list.com
Syncthing
kur2204171034.Syncthing은 디스크 용량이 모자란 노드 방향으로는 sync가 작동하지 않을 수 있다
kur2204171100.남이 만든 것이 오작동해도 화 내지 마라
kur2207122204.Syncthing은 1) 임시 파일 여럿을 만들고 삭제하면서 동기화하며 2) 파일 하나에 대한 파일 시스템 이벤트도 여러번 일어나지만 3) modified time은 한번만 변경된다
kur2301252216.OS마다 파일 이름으로 허용하는 특수문자 집합이 다르다
kur2301252219.여러 OS에서 동기화시키는 파일 이름에 특정 기호를 넣으려면, 기호와 비슷한 유니코드를 사용하면 된다
학습 주도 개발
kur2206092158.학습 주도 개발(Learning Driven Development, LDD)은 학습 활동과 피드백을 정의하고 수행하면서 지식 저장소에 지식을 쌓아나가다 결국 해답을 제시하는 방법론이다
kur2206092201.학습 주도 개발(Learning Driven Development, LDD)은 문제와 상황 등에 따라 다양한 방식으로 구현될 수 있다
kur2206092204.학습 주도 개발(LDD)에서 중요한 것은 지식 저장소, 학습 활동, 피드백 어느 하나라도 빠뜨리지 않는 것이다
kur2207081700.제텔카스텐을 통한 웹 자료 학습은 학습 주도 개발의 실천법이라 할 수 있다
kur2207171200.현대적 설계개발 방법론은 학습이 핵심 원리이나, 그에 대한 명시적 언급이 적다
kur2207171206.현대적 설계개발 방법론이 작동하는 이유이자 핵심 원리는 _개발 구성원의 효과적인 학습_이다
kur2207171223.프로그램은 오직 모델링된 문제만을 해결할 수 있기 때문에, 개발 구성원의 학습이 성공적인 개발에 가장 중요하다
kur2207292233.소프트웨어 프로젝트는 학습 과정이기에, 제조 공정과 같이 완벽하고 고정된 계획은 세울 수 없다
kur2207292307.소프트웨어 프로젝트의 개발 구성원들이 학습을 하기 시작하면, 엄격하고 완벽한 계획은 쓸모가 없어진다
테스트의 망령에서 벗어나다
Premature Constraints sucks
kur2207271320.스펙을 테스트로 짜면서 제품 코드와 함께 발전시키는 TDD 방식은, 잘 될 경우 매우 효과적이다
kur2207271403.개발 초기부터 테스트 코드와 함께 스펙을 발전시킬 수 있는 경우는 보편적이지 않다
kur2207271404.스펙이 불명확한데 억지로 테스트할 때 일어나는 (좋지 않은) 현상
kur2207271407.소프트웨어 프로젝트는 경제적 활동이다
kur2207271415.스펙이 불안정할 땐 REPL을, 안정화되었을 땐 PBT를 써라
TDD only dev sucks - use PBT to aid
kur2207300000.clj test.check의 fmap과 bind 차이
kur2207302145.TDD는 입력 데이터의 코너케이스를 놓치기 쉽고, 다양성이 부족하며, 스펙이 암시적이다
kur2207302150.Red-Green-Refactor 사이클은 제품 코드를 테스트하는 코드를 먼저 작성하라는 TDD의 핵심 원칙을 실천한다
kur2207302201.TDD는 일반적으로 예제 기반 테스팅(Example Based Testing)이다
kur2207302208.테스트 코드는 작동하는 스펙이기에, 급진적인 스펙 변경 시엔 걸림돌이 된다
kur2207302231.프로그래밍에서 제약constraint은 미래에 작성될 수 있는 특정한 코드를 금지하는 무언가이다
kur2207302235.섣부른 제약constraint은 개발 과정의 유연성과 민첩성을 감소시킨다
kur2207302247.PBT generator를 이용하여 입력 데이터를 생성하면 예제 기반 테스트의 단점을 보완할 수 있다
경제적인 테스팅과 함께하는 개발
kur2207302257.테스트 코드를 간결하게 유지하고 꼭 필요할 때만 자동화하면 테스트 코드가 일으키는 유연성 저하를 줄일 수 있다
kur2207302311.테스트에 의존성이 없다면, 대응하는 제품 코드 변경시에만 테스트를 수정하면 된다
kur2207302347.의존성이 없는 테스트는 제품 코드 구현시에 한번만 테스트해도 충분하다
kur2207302351.저수준 모듈의 유닛 테스트는 대부분 비의존 테스트이며 자동화나 회귀 테스트가 필요 없다
kur2208032040.제품 코드를 작성하기 전에 그를 테스트하는 코드를 먼저 작성하는 것이 TDD의 핵심 사상이자 원칙이다
Markdown
Spec
kur2206270714.CommonMark는 표준적이고 모호하지 않은 Markdown마크다운 스펙이다
kur2206280846.마크다운이 널리 사용되면서, 마크다운 기반 앱이 늘어나고 있다
kur2206280902.마크다운 변환기는 다양한 요구 사항을 처리할 수 있도록 충분한 확장성을 제공해야 한다
kur2206280935.마크다운의 최초 개발자는 확장성을 위해 md 스펙을 모호하게 정의했다
kur2206280950.스펙의 모호함이 다양성을 보장하지는 않는다
kur2206281436.마크다운markdown 기반 CMS의 md 파서 요구사항 - 확장성, 날먹, 브라우저 지원
kur2207060844.Markdown footnote 비표준 문법으로 논문의 Bibliography스러운 참조가 가능하다
CLJS (markdown-it)
kur2206292140.ClojureScript는 고급 최적화 컴파일 옵션 적용 시, 심볼 이름 변경으로 인해 외부 라이브러리를 쓸 수 없다
kur2206292142.ClojureScript에서 외부 JS 라이브러리의 심볼을 require하려면 extern을 이용하여 Google Closure Compiler의 이름 변경을 막아야 한다
kur2206292144.CLJSJS는 npm 모듈을 cljs에서 사용하기 위해 필요한 것들을 jar 파일로 묶은 패키지다
kur2206292149.CLJSJS 패키지는 신뢰할 수 없으며, 일반적으로 대응하는 npm 모듈보다 버전이 낮다
kur2206292152.shadow-cljs는 자동화되고 간단히 개입 가능한 extern inference 기능을 제공한다
kur2207122148.ncc, webpack, rollup 등을 이용하여 사용하는 npm 모듈이 모두 들어간 standalone js 파일을 만들어 배포할 수 있다
Run JS md parser in CLJ(JVM)
kur2207142131.javax의 ScriptEngine은 js를 jvm 바이트코드로 컴파일하여 jvm에서 js 스크립트를 실행할 수 있게 한다
kur2207142212.javax의 ScriptEngine은 ES6, node 모듈에 대한 지원이 부족하므로, node 라이브러리를 쓰려면 J2V8을 쓰는 것이 낫다
kur2207142220.J2V8은 V8 런타임에 대한 Java binding 집합으로, java에서 v8, 특히 node.js의 모듈과 함수를 쓸 수 있게 한다
kur2208231559.J2V8은 V8 런타임을 생성한 쓰레드에 lock을 줘서 싱글 쓰레드 실행을 보장하며, 다른 쓰레드 접근 시 Exception을 일으킨다
Deploy
embedded jetty?
kur2207072126.Jetty는 ini xml mod 등 다양한 형식의 설정 파일이 있으나, 이들은 모두 결국 POJO를 통한 config의 다른 표현이다
kur2207072201.Embedded Jetty는 프로그램의 lib처럼 작동하며, POJO를 조작하는 자바 코드로 config한다
kur2207072236.Clojure ring의 run-jetty는 간단한 opt-map을 받아 jetty-server를 만들고 ssl, async, join 등 여러가지 jetty 서버 config를 대신 해준다
embedded sucks..
kur2212281110.임베디드 http 서버는 배포용이 아니다
kur2212281633.forward proxy는 서버에게 클라이언트처럼 작동하며, reverse proxy는 클라이언트들에게 서버처럼 작동한다.
kur2212281648.리버스 프록시는 보안, 성능, 신뢰성 등으로 인해 서버 배포에서 거의 필수적이다
kur2212281701.리버스 프록시는 클라이언트들이 접속하는 서버를 앱 서버와 분리하고, 클라의 요청을 앱 서버로 포워딩한다
kur2301042114.솔루션의 타당성을 조사할 때, 솔루션의 일부를 바꾸어 조사해보는 것이 도움이 될 수 있다
kur2301042132.문제나 솔루션에서 비주류인 부분을 주류인 부분으로 바꿔보면 솔루션이 타당한지 확인할 수 있다
JVM Deploy
kur2212281627.Clojure 프로젝트를 deploy하는 방법은 크게 1) 실행파일(jar)을 그대로 배포하는 법과 2) 여러 앱을 하나의 JVM 위(컨테이너)에 올리는 방법이 있다
kur2212281628.JVM 컨테이너는 각 앱들이 JVM을 각자 실행하는 것처럼 추상화하면서, 실제로는 하나의 JVM 위에 앱 여럿을 실행한다
secret ?
kur2207111700.stdin을 이용하여 server 프로세스에 secret 안전하게 주입하기
kur2207111708.Secret Manager 서비스는 어플리케이션의 secret을 안전하게 관리하여, 하드코딩된 secret을 없애고 주기적으로 자동화된 secret 변경이 가능케 한다
kur2209211019.시스템에 secret을 저장하는 다앙한 방법
kur2209211536.시스템에 secret을 어떤 형식으로 저장해도, 시스템이 compromised될 경우 결국 보안을 유지할 수 없다
kur2209211551.가장 안전한 방법은 1) 신뢰할 수 있는 외부 시스템에서 2) 런타임에 가져온 암호화된 비밀 데이터를 3) 런타임에 복호화해서 쓰는 것이다
배포 자동화(CD)
kur2301281908.ssh는 서버가 공개키를, 클라이언트가 비밀키를 보관하고, 비밀키를 이용하여 클라이언트를 신뢰할 수 있는지 인증Authentication한다
kur2301282109.github actions는 깃헙 레포에서 특정 이벤트가 일어날 때, vm에서 다양한 작업을 수행할 수 있는 플랫폼이다
kur2301282113.github actions은 작업과 실행 조건, 실행할 머신 등을 yaml과 쉘 커맨드로 이뤄진 DSL로 표현한다
kur.blog.monitor
Java/Clojure file system watcher
kur2207100725.Clojure로 구현된 filesystem watcher 라이브러리들은 모두 오래 되고 방치되었는데, 그나마 hawk가 쓸만해 보인다
kur2207100742.Java 7 이상부터 지원하는 WatchService는 하위 OS의 구현에 의존하거나, 간단한 polling을 쓴다
kur2207100754.각종 지표(date of latest commit, num of star, fork, issue, contributor)로 오픈소스 라이브러리의 활성화, 대중성을 확인할 수 있다
7 Concurrency
kur2207192032.thread와 primitive lock을 이용하는 동시성 프로그래밍 원칙 - memory visibility 문제, race condition, deadlock을 피하려면
kur2207202158.함수형 패러다임이 동시성과 병렬성 구현에 효과적인 이유는, 불변성에 의한 참조 투명성이 계산 순서 변경을 자유롭게 하기 때문이다
kur2207202216.Thread와 Lock은 직접적으로는 병렬성을 지원하지 않는다
kur2207242048.참조 투명성(Referential Transparency)은 프로그램의 표현식을 대응하는 값으로 바꾸어도 실행에 영향을 주지 않는 것을 의미한다
kur2207242108.순수 함수는 1) 동일 입력에 대해 동일 출력을 보장하며 2) 사이드 이펙트를 일으키지 않는 함수다
kur2207242124.순수 함수의 동일 입력 - 동일 출력 속성이 참조 투명성을 보장한다
웹 사용성
kur2208212043.평범한 사람a이 도구를 써서 뭔가 할 때b, 사용법을 스스로 알아낼 수 있으며c, 이 때 필요한 수고보다 도구가 제공하는 가치가 클 때d - '사용성이 좋다' 고 한다
kur2208212115.좋은 사용성의 절대 원칙 - 사용자를 고민에 빠뜨리지 마라
kur2208232100.웹 페이지는 what, where, how가 자명해야 사용자가 고민하지 않는다
kur2208232122.what, where, how가 자명하지 않은 사이트를 볼 때 사용자의 머리속에는 수많은 물음표가 떠오른다
kur2208232142.명백하고 자명하기 어렵다면 최소한 추가 설명이나 메뉴얼 없이 이해하고 사용할 수 있어야 한다
통신 보안
암호화 알고리즘
kur2301270854.비대칭 키 암호화는 공개키를 공개하는 주체가 실제 공개키 발급자인지 보증할 수 없어 중간자 공격에 취약하다
kur2301271306.대칭 키 암호화 알고리즘 하나의 키K로 암호화-복호화를 하며, 통신 대상(a,b)은 비밀키K를 하나만 공유하면 양방향으로 암호화된 통신이 가능하다
kur2301271314.비대칭 키 암호화는 쌍을 이루는 두개의 키(X,Y)를 쓰는데, X로 암호화했다면 Y로 복호화해야 하며, Y로 암호화했다면 X로 복호화해야 한다
kur2301271327.비대칭 키 알고리즘은 비밀키 공유 없이 암호화 통신이 가능하다
kur2301271330.대칭 암호화 알고리즘은 성능이 좋아 실제 통신 데이터 암호화에 쓰이며, 그에 비해 느린 비대칭 암호화 알고리즘은 대칭 알고리즘을 위한 비밀키 교환에 쓰인다
HTTPS
kur2301271332.HTTPS(Hypertext Transfer Protocol Secure)는 TLS(Transport Layer Security)를 적용하여 웹에서의 보안 통신이 가능케 하는 HTTP 프로토콜의 확장이다
kur2301271333.HTTPS는 일반적인 암호 기술이 제공하는 3가지 특성 - 기밀성Confidentiality, 무결성Integrity, 인증Authentication을 웹 통신에 제공한다
kur2301271337.HTTPS는 1) 비밀키 교환용 비대칭 키 알고리즘, 2) 신원 인증서, 3) 평문 메시지 암호화용 대칭 키 알고리즘, 4) 메시지 다이제스트 해싱 알고리즘으로 구성된다
kur2301271339.TLS의 암호화 스위트cipher suite는 키 교환 (비대칭) 알고리즘, 평문 (대칭) 암호화 알고리즘, 메시지 인증 코드(message authentication code, MAC) 알고리즘으로 구성된다
Certificate Authority
kur2207051340.인증기관(Certificate Authority, CA)은 (HTTPS) 인증서Certificate를 통해 공개키와 공개키 발행자(도메인)의 관계를 보증한다
kur2207052144.공개키 인증서 발급을 위해서는 CA와 요청자 사이에 상호작용이 필요한데, 이를 위한 표준이 ACME 프로토콜이다
kur2301271936.Lets Encrypt는 전 인터넷의 보안을 끌어 올리기 위해 설립된 Certificate Authority으로, 90일 보증 무료 Domain Validation(DV) 인증서와 인증 신청, 설치, 갱신을 자동화하는 Certbot을 제공한다
kur2301272032.Certbot은 1) certificate 얻기와 2) certificate를 서버에 install 하는 과정을 자동화한다
kur2301272041.AWS Certificate Manager(ACM)를 이용하여 SSL TLS 인증(HTTPS)을 받으려면 Application Load Balancer(ALB)를 쓰거나 CDN에 배포해야만 한다
etc..
kur2206082220.인터넷의 정보는 변경or삭제될 수 있어 불안정하다
kur2206082226.인터넷에서 안정적으로 정보를 수집하기 위한 개인 파일 아카이브가 필요하다
kur2206082238.다양한 웹 정보 수집, 아카이브 방법
kur2301262019.unix-like OS에서, 조상 디렉토리에 read 권한이 없으면 그 아래 있는 모든 파일을 읽을 수 없다
kur2301262031.프로세스는 uid, gid와 함께 생성되며, 파일에 대한 권한은 이들을 따른다