2024-07-25-TIL
2024-07-25-TIL
Today I Learned
JavaScript Closure
클로저는 함수가 자신이 정의된 시점의 렉시컬 환경(바깥 스코프의 변수)을 기억하고, 바깥 함수가 끝난 뒤에도 그 변수에 접근할 수 있는 성질이다. 바깥 함수의 지역 변수는 반환된 내부 함수를 통해서만 접근할 수 있으므로, 클래스의 private 필드처럼 상태를 숨기는 데 쓸 수 있다.
1
2
3
4
5
6
7
8
9
10
function createCounter() {
let count = 0; // 외부에서 직접 접근할 수 없음
return {
increment() { return ++count; },
get() { return count; },
};
}
const counter = createCounter();
counter.increment(); // 1
첫 번째 질문의 최다 추천 답변은 “객체는 가난한 자의 클로저”라는 Qc Na 우화를 인용하며, 클로저와 객체가 서로를 흉내 낼 수 있는 대등한 도구라는 점을 보여 준다. Java의 클래스처럼 상태와 동작을 묶는 구조를 JavaScript에서는 클로저만으로도 만들 수 있다.
LazyInitializationException in Spring Data JPA
LazyInitializationException은 지연 로딩 프록시나 컬렉션을 영속성 컨텍스트가 닫힌 뒤에 처음 접근할 때 발생한다. 서비스 메서드의 트랜잭션이 끝난 뒤 컨트롤러나 JSON 직렬화 단계에서 연관 엔티티를 건드리는 경우가 전형적이다.
올바른 해결은 트랜잭션 안에서 필요한 연관 데이터를 미리 가져오는 것이다.
- JPQL
join fetch로 연관 엔티티를 한 번에 조회한다. - Spring Data JPA 메서드에
@EntityGraph(attributePaths = ...)를 지정한다. - 엔티티 대신 필요한 필드만 담은 DTO로 조회해 반환한다.
피해야 할 방법도 있다. Hibernate의 hibernate.enable_lazy_load_no_trans를 켜면 예외는 사라지지만, Vlad Mihalcea는 이를 안티패턴으로 본다. 지연 로딩이 일어날 때마다 임시 세션을 열어 새 DB 커넥션과 트랜잭션을 잡기 때문에, 연관 객체 수만큼 커넥션 획득과 쿼리가 반복되는 N+1 문제가 생기고 커넥션 풀에 부담을 준다. 근본 원인을 감추는 설정이라는 것이다.
Best Practice Hibernate Fetch
JPA의 기본 fetch 전략은 연관 관계 종류마다 다르다. @ManyToOne, @OneToOne은 기본이 EAGER이고, @OneToMany, @ManyToMany는 기본이 LAZY다.
일반적인 권장은 모든 연관 관계를 LAZY로 두고, 필요한 화면이나 유스케이스마다 fetch join이나 엔티티 그래프로 함께 가져올 대상을 정하는 것이다. EAGER는 엔티티를 조회할 때마다 연관 엔티티까지 항상 가져오므로, 필요 없는 조인이 생기고 JPQL로 목록을 조회할 때는 연관 엔티티를 위한 쿼리가 행마다 추가로 나가는 N+1 문제가 생기기 쉽다. 한 번 EAGER로 정하면 특정 쿼리에서만 끄기도 어렵다.
1
2
3
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id")
private Team team;
Java Serialization
직렬화는 객체를 바이트 스트림으로 바꿔 파일, 네트워크, 캐시에 저장하거나 전송할 수 있게 하는 것이고, 역직렬화는 그 반대다. Java 기본 직렬화는 클래스가 Serializable 마커 인터페이스를 구현하면 ObjectOutputStream으로 쓸 수 있다.
transient필드는 직렬화에서 제외된다.serialVersionUID는 클래스 버전을 나타낸다. 명시하지 않으면 클래스 구조로 자동 계산되므로, 필드를 하나만 바꿔도 값이 달라져 기존 데이터를 역직렬화할 때InvalidClassException이 날 수 있다. 그래서 직렬화를 쓴다면 직접 선언하는 것이 안전하다.- 직렬화된 데이터에는 클래스 이름이 들어가므로 패키지나 클래스 이름이 바뀌면 읽을 수 없다.
이런 이유로 Java 기본 직렬화는 Java 프로세스 사이에서 잠깐 쓰는 용도가 아니라면 잘 쓰지 않고, 외부 저장소나 다른 시스템과 주고받는 데이터는 JSON 같은 언어 중립적인 형식을 선호한다. 신뢰할 수 없는 데이터를 역직렬화하는 것은 보안 취약점의 원인이 되기도 한다.
owasp-java-html-sanitizer
게시판이나 에디터처럼 사용자가 작성한 HTML을 그대로 화면에 보여 줘야 하면 XSS를 막기 위해 위험한 태그와 속성을 제거해야 한다. 모든 HTML을 이스케이프하면 서식까지 사라지므로, 허용할 요소만 남기는 화이트리스트 방식의 sanitizer를 쓴다.
OWASP Java HTML Sanitizer는 서드파티가 작성한 HTML을 XSS로부터 보호하면서 포함할 수 있게 해 주는 Java 라이브러리다. 런타임 의존성이 없고, 미리 정의된 정책을 조합하거나 HtmlPolicyBuilder로 직접 정책을 만든다.
1
2
3
4
5
6
7
8
9
PolicyFactory policy = Sanitizers.FORMATTING.and(Sanitizers.LINKS);
String safeHtml = policy.sanitize(untrustedHtml);
PolicyFactory custom = new HtmlPolicyBuilder()
.allowElements("a", "p", "b", "i")
.allowUrlProtocols("https")
.allowAttributes("href").onElements("a")
.requireRelNofollowOnLinks()
.toFactory();
정책은 허용할 것만 명시하고, 나머지는 모두 제거되도록 하는 것이 원칙이다.
AI 키워드
2024년 7월 25일 Google DeepMind는 AlphaProof와 AlphaGeometry 2가 국제수학올림피아드(IMO) 문제 여섯 개 중 네 개를 풀어 은메달 수준에 도달했다고 발표했다. AI 시스템이 IMO에서 메달 수준에 이른 첫 사례다. 출처는 Wikipedia의 2024 in artificial intelligence 항목이다.
참고한 자료외부 출처 20
외부 출처
- stackoverflow.com/questions/501023/closures-and-objects
- softwareengineering.stackexchange.com/questions/307083/javascript-closure-style-similar-to-java-class-structure
- (Spring Data JPA) LazyInitializationException 오류 해결 방법
- JPA의 LazyInitializationException
- The hibernate.enable_lazy_load_no_trans Anti-Pattern
- ::JPA:: @EntityGraph로 lazy 처리하기
- JPA) Entity Graph 로 N+1 이슈 해결하기
- medium.com/jpa-java-persistence-api-guide/hibernate-lazyinitializationexception-solutions-7b32bfc0ce98
- LazyInitializationException - What it is and the best way to fix it
- stackoverflow.com/questions/39872070/hibernate-good-practice-lazy-eager-loading-and-saving-deleting-children-help-m
- Eager/Lazy Loading in Hibernate Baeldung
- suryasispaul.medium.com/lazy-and-eager-loading-in-hibernate-9fb4b8e229b4
- Hibernate Best Practices
- Best practice for fetch
- · JAVA 직렬화(Serialization)과 역직렬화(Deserialization)
- (Java) 직렬화(Serialization)와 역직렬화(Deserialization)란? transient 변수란?
- ☕ 자바 직렬화(Serializable) - 완벽 마스터하기
- 직렬화(Serialization)와 역직렬화(Deserialization)
- owasp-java-html-sanitizer 에 대해 알아보자
- java-html-sanitizer/owasp-java-html-sanitizer at main · OWASP/java-html-sanitizer
댓글
아직 댓글이 없습니다