2023-11-16-TIL
2023-11-16-TIL
Today I Learned
Vanilla Software
바닐라 자바스크립트, 바닐라 쿠버네티스 같은 말이 종종 보이는데, ‘바닐라’라는 말은 오리지널 버전을 그대로 사용하는 것을 의미한다. 우리나라 말로 치자면 ‘순정’같은 느낌인 것 같다.
위키백과에 따르면 이 말은 아무것도 얹지 않은 바닐라 아이스크림에서 왔고, 단순함과 표준화, 유지보수의 쉬움을 강조할 때 쓴다. 바닐라 쿠버네티스라고 하면 클라우드 업체나 배포판이 덧붙인 기능 없이 업스트림 쿠버네티스를 그대로 쓴다는 뜻이다.
- https://en.wikipedia.org/wiki/Vanilla_software
Java Record Polymorphism
레코드는 클래스를 상속할 수 없다. Stack Overflow 질문에서도 인용되는 JEP 395의 설명은, 레코드가 헤더에 적은 컴포넌트만으로 상태가 정해지는 투명한 데이터 운반체이므로 상위 클래스에서 상태를 물려받으면 그 성질이 깨진다는 것이다. 대신 인터페이스는 구현할 수 있으므로, 다형성이 필요하면 공통 인터페이스를 두고 레코드가 구현하게 한다.
이 레코드들을 JSON DTO로 쓰려면 Jackson이 어떤 구현 타입으로 역직렬화할지 알아야 한다. bwgjoseph 글은 인터페이스에 @JsonTypeInfo와 @JsonSubTypes를 붙이는 방법을 보여 준다. 특히 JsonTypeInfo.Id.DEDUCTION을 쓰면 타입 이름 필드 없이 JSON에 있는 필드 구성만 보고 구현 타입을 추론한다.
1
2
3
4
5
6
7
8
9
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
@JsonSubTypes({
@JsonSubTypes.Type(HomeAddress.class),
@JsonSubTypes.Type(OfficeAddress.class)
})
interface Address {}
record HomeAddress(String street, String unit) implements Address {}
record OfficeAddress(String street, String company) implements Address {}
- https://stackoverflow.com/questions/71139939/why-java-records-do-not-support-inheritance
- https://bwgjoseph.com/polymorphic-dto-using-java-record-with-jackson
AWS MediaConvert
AWS Elemental MediaConvert는 파일 기반 영상 처리 서비스다. S3에 있는 원본 영상을 입력으로 받아 다른 코덱과 해상도로 트랜스코딩하고, HLS나 DASH 같은 스트리밍 형식으로 패키징해 다시 S3에 쓴다. 인코딩 서버를 직접 운영하지 않고 작업(job) 단위로 요청하는 방식이라, 업로드 이벤트로 Lambda를 실행해 MediaConvert 작업을 만드는 구성이 흔하다.
- https://aws.amazon.com/ko/mediaconvert/
- https://docs.aws.amazon.com/mediaconvert/latest/ug/what-is.html
Media File Hash Difference
영상이나 음원같은 미디어 파일도 해시값으로 동일성 비교가 될까? DTW나 Finger Print 같은 기법을 추가로 사용하는 이유가 무엇일까?
- https://mediahashlist.org/wp-content/uploads/2012/01/Media-Hash-File-Format-Proposal-v1_3.pdf
- https://www.digitalvolcano.co.uk/duplicatecleanermanual/what_is_the_difference_between_the_content_comparison___hashing_types_.htm
- https://stackoverflow.com/questions/38489876/how-to-compare-files-using-byte-array-and-hash
- https://www.reddit.com/r/ffmpeg/comments/wbvio2/comparing_video_files_that_are_supposed_to_be/
바이트값 하나하나 비교한다면 당연히 완전하게 동일함을 보장하겠지만, 성능이슈로 그렇게 처리하지 않는것 같다.
해시로 비교할 수 있는 것은 “바이트까지 같은 파일”이다. 같은 파일을 복사한 사본을 찾는 데는 해시가 정확하고 빠르다. 바이트 전체를 비교하지 않고 해시값만 비교해도 되는 이유가 바로 그 성능이다. 문제는 미디어에서 알고 싶은 것이 대개 “같은 내용인가”라는 점이다. 같은 노래라도 비트레이트를 바꿔 다시 인코딩하거나 앞에 무음이 조금 붙으면 바이트가 완전히 달라지고, SHA-256 같은 암호학적 해시는 바이트 하나만 달라도 전혀 다른 값이 된다.
그래서 내용 기반 비교 기법이 따로 쓰인다.
- 음향 핑거프린트: 위키백과는 사람 귀에 비슷하게 들리면 바이너리 표현이 크게 달라도 핑거프린트가 일치해야 한다고 설명한다. 압축으로 인코딩이 크게 바뀌어도 같은 녹음으로 식별할 수 있게 만드는 것이 목표다.
- 지각 해시(perceptual hash): 미디어의 특징이 비슷하면 해시도 비슷하게 나오도록 만든 locality-sensitive hash다. 작은 변화에 값이 완전히 바뀌는 암호학적 해시와 반대 성질이다.
- DTW(Dynamic Time Warping): 속도가 다를 수 있는 두 시계열의 유사도를 재는 알고리즘이다. 재생 속도나 시작 지점이 조금 어긋난 두 오디오의 특징 시퀀스를 맞춰 비교할 때 쓴다.
Fingerprint vs Hash
위키백과의 Fingerprint (computing)는 핑거프린트를 큰 데이터를 실용적으로 유일하게 식별하는 짧은 비트열로 정의하고, 큰 데이터를 비교하거나 전송하지 않으려고 쓴다고 설명한다. 이 의미의 핑거프린트는 해시 함수로 만든 값과 거의 같다. 위의 미디어 비교에서는 “핑거프린트”가 내용의 특징을 요약한 값이라는 좁은 뜻으로 쓰이므로, 문맥에 따라 둘의 관계가 달라진다는 점을 구분해 두면 된다.
- https://math.stackexchange.com/questions/2512517/whats-the-difference-between-a-fingerprint-and-a-hash
- https://www.technologyreview.com/2004/08/04/232539/fingerprinting-your-files/
CNAME vs Entry Point
Cloudflare 문서에 따르면 CNAME 레코드는 별칭 도메인을 정식(canonical) 도메인으로 가리킨다. blog.example.com이 example.com을 CNAME으로 가리키면, DNS 조회는 example.com의 A 레코드를 따라가 IP를 얻는다. 서버 IP가 바뀌어도 A 레코드 하나만 고치면 된다는 장점이 있다.
제약도 있다. CNAME이 있는 이름에는 MX, TXT, A 같은 다른 레코드를 함께 둘 수 없다. 그래서 다른 레코드가 반드시 있어야 하는 루트 도메인(apex, example.com)에는 표준 CNAME을 쓸 수 없다. 서비스의 진입점 도메인을 CDN이나 로드 밸런서 주소로 연결하려 할 때 이 제약에 부딪힌다. DNSimple 문서의 ALIAS 레코드나 Cloudflare의 CNAME flattening처럼, DNS 서버가 대상 주소를 대신 조회해 A 레코드처럼 응답하는 기능이 이 문제를 푼다.
- https://en.wikipedia.org/wiki/CNAME_record#:~:text=A%20Canonical%20Name%20(CNAME)%20record,from%20a%20single%20IP%20address.
- https://www.cloudflare.com/ko-kr/learning/dns/dns-records/dns-cname-record/
- https://support.dnsimple.com/articles/differences-between-a-cname-alias-url/
- https://support.dnsimple.com/articles/differences-a-cname-records/
- https://easydmarc.com/blog/cname-vs-a-record/
Today I Studied
Loop Unrolling
루프 풀기는 반복문 본문을 여러 번 복제해 반복 횟수를 줄이는 최적화다. 매 반복마다 실행하는 인덱스 증가와 종료 조건 검사, 분기를 줄이고, 메모리 읽기 지연을 다른 연산 뒤에 숨기는 것이 목적이다. 대가로 코드 크기가 커진다. 요즘은 컴파일러가 알아서 판단해 적용하는 경우가 많다.
1
2
3
4
5
6
// 원래 루프
for (int i = 0; i < n; i++) sum += a[i];
// 4배 풀기 (n이 4의 배수라고 가정)
for (int i = 0; i < n; i += 4)
sum += a[i] + a[i + 1] + a[i + 2] + a[i + 3];
- https://www.youtube.com/watch?v=U_T-hPz6j50
- https://www.sciencedirect.com/topics/computer-science/loop-unrolling
Duff’s Device
루프를 풀면 반복 횟수가 풀기 배수로 나누어떨어지지 않을 때 남는 부분을 처리해야 한다. Duff’s device는 C의 switch와 do-while을 겹쳐서 이를 해결한 기법이다. 위키백과에 따르면 1983년 Lucasfilm에 있던 Tom Duff가 실시간 애니메이션 프로그램을 빠르게 하려고 고안했다. switch로 나머지 개수에 해당하는 위치로 루프 본문 한가운데에 바로 뛰어들고, 그다음부터는 풀린 루프가 그대로 이어진다. C에서 case 레이블이 do-while 블록 안에 들어가도 문법상 허용된다는 점을 이용한다.
- https://johngrib.github.io/wiki/duff-s-device/
- https://www.geeksforgeeks.org/duffs-device-work/
- https://en.wikipedia.org/wiki/Duff%27s_device
- https://lethean.github.io/2006/01/11/duffs-device/
MapReduce
MapReduce는 대용량 데이터를 여러 서버에서 병렬로 처리하는 프로그래밍 모델이다. 원래 Google 내부 기술의 이름이었고, Apache Hadoop의 오픈소스 구현으로 널리 퍼졌다.
- Map: 입력을 나눠 각 조각에서 (키, 값) 쌍을 만든다. 단어 세기라면 각 단어마다
(단어, 1)을 낸다. - Shuffle: 같은 키를 가진 쌍을 같은 서버로 모은다.
- Reduce: 키별로 값을 합쳐 결과를 낸다.
(단어, [1, 1, 1])을(단어, 3)으로 줄인다.
영문 위키백과는 이 모델의 핵심 기여가 map과 reduce 함수 자체가 아니라, 프레임워크가 분산 서버 간 작업 배치, 통신, 데이터 전송, 장애 대응을 맡아 준다는 데 있다고 설명한다.
- https://songsunbi.tistory.com/5
- https://kadensungbincho.tistory.com/112
- https://ko.wikipedia.org/wiki/%EB%A7%B5%EB%A6%AC%EB%93%80%EC%8A%A4
- https://12bme.tistory.com/154
댓글
아직 댓글이 없습니다