2023-08-17-TIL
2023-08-17-TIL
Today I Learned
Runnable vs Thread
Thread의 Javadoc은 새 스레드를 만드는 방법을 두 가지로 소개한다. Thread를 상속해 run()을 오버라이드하는 방법과, Runnable을 구현한 객체를 Thread 생성자에 넘기는 방법이다.
1
new Thread(() -> System.out.println("work")).start();
보통은 Runnable 쪽이 권장된다. Runnable은 “무엇을 실행할지”만 담고, Thread는 “어떻게 실행할지”를 맡으므로 두 책임이 분리된다. Java는 단일 상속만 허용하므로 Thread를 상속하면 다른 클래스를 상속할 수 없다는 제약도 있다. 무엇보다 Runnable로 작업을 표현해 두면 스레드를 직접 만들지 않고 ExecutorService 같은 스레드 풀에 그대로 넘길 수 있다. run()을 직접 호출하면 새 스레드가 생기지 않고 현재 스레드에서 실행된다는 점도 헷갈리기 쉽다. 새 스레드는 start()를 호출해야 만들어진다.
- https://hyeo-noo.tistory.com/293
Serializable
직렬화는 객체를 바이트 스트림으로 바꿔 파일에 저장하거나 네트워크로 보내고, 나중에 다시 객체로 복원하는 것이다. Serializable Javadoc에 따르면 이 인터페이스는 메서드도 필드도 없는 표시용(marker) 인터페이스이고, 구현하지 않은 클래스의 상태는 직렬화되지 않는다.
같은 문서에서 serialVersionUID를 직접 선언하라고 강하게 권한다. 선언하지 않으면 런타임이 클래스 구조를 바탕으로 기본값을 계산하는데, 이 값은 컴파일러 구현에 따라 달라질 수 있다. 그러면 클래스를 조금만 바꿔도 이전에 직렬화한 데이터를 역직렬화할 때 InvalidClassException이 날 수 있다. 직렬화에서 빼고 싶은 필드는 transient로 표시한다.
언제 구현해야 하는가는 객체가 JVM 밖으로 Java 직렬화 방식으로 나가는가로 판단하면 된다. HTTP 세션 복제, Java 직렬화를 쓰는 캐시나 원격 호출이 대표적인 예다. JSON으로 주고받는 DTO처럼 Jackson이 변환하는 객체에는 필요하지 않다.
- https://stackoverflow.com/questions/4548816/when-should-we-implement-serializable-interface
- https://www.digitalocean.com/community/tutorials/serialization-in-java
- https://developerhjg.tistory.com/34
- https://change-words.tistory.com/entry/%EC%9E%90%EB%B0%94-JAVA-implements-Serializable-%EC%A7%81%EB%A0%AC%ED%99%94%EB%9E%80-%EC%82%AC%EC%9A%A9-%EC%9D%B4%EC%9C%A0
Today I Studied
Hard Real-Time System vs Soft Real-Time System
실시간 시스템은 빠른 시스템이 아니라 정해진 마감 시간(deadline) 안에 응답을 보장하는 시스템이다. 위키백과는 마감을 놓쳤을 때의 결과로 세 가지를 구분한다.
- Hard: 마감을 놓치면 시스템 전체의 실패다. 자동차 엔진 제어, 심장 박동기가 예로 나온다.
- Firm: 가끔 놓치는 것은 견딜 수 있지만, 마감이 지난 결과는 쓸모가 없다.
- Soft: 마감이 지나도 결과를 쓸 수는 있지만 가치가 점점 떨어진다. 영상 스트리밍에서 프레임이 늦게 오면 끊김이 생기는 정도의 문제가 이쪽이다.
웹 서비스에서 말하는 “실시간”은 대개 soft real-time에 가깝다.
- https://grapevine9700.tistory.com/126
- https://www.geeksforgeeks.org/difference-between-hard-real-time-and-soft-real-time-system/
- https://byjus.com/gate/difference-between-hard-real-time-and-soft-real-time-system/
- https://stackoverflow.com/questions/17308956/differences-between-hard-real-time-soft-real-time-and-firm-real-time
Google Docs Real-Time System
Google Docs 같은 협업 에디터는 여러 사용자가 같은 문서를 동시에 고친다. hackerwins 블로그는 이 구조를 Git에 비유한다. 각자 로컬에서 바로 편집하고 변경을 서버와 주고받아 합치는 구조라는 것이다. 문제는 동시 편집이다. A가 2번 위치에 글자를 넣는 사이 B가 3번 위치에 글자를 넣었다면, B의 연산을 그대로 A의 문서에 적용하면 위치가 어긋난다. 그래서 상대 연산을 받을 때 내 연산을 고려해 위치를 변환하는 OT(Operational Transformation)나, 연산 순서와 무관하게 같은 결과로 수렴하도록 자료구조를 설계하는 CRDT가 쓰인다.
- https://hackerwins.github.io/2019-04-16/co-editor
Kafka Exactly-Once Delivery
Kafka에서는 지원하지만 성능 이슈가 있는것으로 알려져있어서 다른 대안을 사용한다.
Confluent 글에 따르면 Kafka의 exactly-once는 두 기능으로 이루어진다.
- 멱등 프로듀서: 메시지 배치마다 시퀀스 번호를 붙여, 재시도로 같은 배치가 다시 와도 브로커가 중복을 버린다.
- 트랜잭션: 여러 파티션에 대한 쓰기를 원자적으로 묶는다. 컨슈머는
isolation.level=read_committed로 커밋된 메시지만 읽는다.
같은 글은 이 보장이 Kafka Streams 내부 처리 범위에서만 성립하고, 처리 중 외부 DB를 갱신하거나 RPC를 호출하는 부수 효과는 보장 대상이 아니라고 명시한다. bulloak 블로그는 더 일반적으로, 신뢰할 수 없는 네트워크에서 exactly-once 전달은 두 장군 문제와 같은 이유로 불가능하다고 주장한다. 그래서 실무의 대안은 at-least-once로 전달하고 받는 쪽을 멱등하게 만드는 것이다. 메시지 ID로 처리 여부를 기록해 두고 중복이면 건너뛰는 방식이 대표적이다.
- https://devs0n.tistory.com/74
- https://blog.bulloak.io/post/20200917-the-impossibility-of-exactly-once/
- https://news.ycombinator.com/item?id=34986691
SEO
SEO(Search Engine Optimization)는 검색 엔진이 사이트의 콘텐츠를 잘 이해하고, 사용자가 검색으로 그 콘텐츠를 찾을 수 있게 돕는 작업이다. Google 검색 센터의 SEO 기본 가이드는 검색 엔진도 사이트의 사용자 중 하나라는 관점으로 설명을 시작한다. 가이드에서 다루는 기본기는 이렇다.
- 크롤러가 페이지를 찾을 수 있게 링크 구조와 사이트맵을 갖춘다.
- 검색 결과의 제목 링크와 스니펫이 되는
<title>과 meta description을 페이지마다 구체적으로 쓴다. 읽기 쉽고 유용한 콘텐츠를 만들고, 중복 페이지는 정규 URL로 정리한다.
- https://ko.wix.com/blog/post/what-is-seo
- https://www.ascentkorea.com/seo-complete-guide-2022/
- https://seo.tbwakorea.com/blog/seo-guide-2022/
- https://library.gabia.com/contents/domain/4359/
- https://developers.google.com/search/docs/fundamentals/seo-starter-guide?hl=ko
댓글
아직 댓글이 없습니다