NewsFilter Chrome Extension — Privacy Policy

뉴스필터 크롬 확장 프로그램 — 개인정보 처리방침 시행일: 2025-08-10 1) 개요 본 확장 프로그램은 AI 기반 기사 품질 평가 기능을 제공합니다. 데이터 최소 수집 원칙을 준수합니다. 2) 수집 항목 익명 토큰: 기기 간 동기화를 위해 chrome.storage.sync에 저장되는 무작위 토큰 URL 해시: 현재 페이지 URL의 SHA‑256 해시값(원본 URL은 서버로 전송하지 않음) 사용자가 자발적으로 제출한 피드백: 점수, 태그, 선택 코멘트 다음 정보는 수집하지 않습니다: 개인식별정보, 정확한 위치, 방문기록 목록, 키 입력/마우스 추적, 페이지 콘텐츠. ...

August 10, 2025

WebFlux Flow Chart

× This post explains the flow of WebFlux request processing through detailed sequence diagrams. ...

August 7, 2025

Java NIO Overview and Example

Java NIO Purpose Netty is a library that abstracts Java NIO, so Java NIO is often discussed. This post provides a brief explanation. Features NonBlocking I/O I/O operations can be performed asynchronously without waiting Multiple connections can be implemented in a non-blocking way (Selectors) Channels Bidirectional communication Unlike InputStream and OutputStream, a single channel can perform both read and write Direct Buffer support Performance improvement by reducing buffer copy overhead through memory-mapped buffers Read/write for socket communication is only supported with native memory - stack overflow (Java Champion’s answer) Native memory is part of the JVM’s native area If you use a buffer created in JVM heap memory for socket communication, there is overhead from copying to native memory To reduce buffer copy overhead, direct buffers are introduced, which are created and written directly in native memory Due to direct buffer optimization, there is a difference in the number of direct buffers between Webflux and MVC models - https://oss.navercorp.com/nspa/nspa-server/issues/3219#issuecomment-14853076 MVC: 200~300 Webflux: 75 Main Components Selector Handles events for multiple channels in a non-blocking way ServerSocketChannel Server socket channel. Supports bidirectional communication. By implementing SelectableChannel, Selector can register to receive events for the channel. SelectionKey Token issued when registering a channel with a Selector. Represents the connection between selector and channel. ...

June 2, 2025

select vs poll vs epoll: Comparison and Netty Context

select vs poll vs epoll Purpose Netty uses epoll. Understanding how epoll works helps in understanding Netty. By comparing various I/O handling methods, we can better understand epoll. Select The user program registers interested events for each file descriptor in a set The user program keeps checking for events on fds in the set Handles the occurred events Time complexity O(N) [N = number of registered events] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/select.h> #include <fcntl.h> int main() { int fd1 = STDIN_FILENO; // Standard input int fd2 = open("file2.txt", O_RDONLY); // Another file int fd3 = open("file3.txt", O_RDONLY); // Another file if (fd2 == -1 || fd3 == -1) { perror("Failed to open files"); return 1; } // Initialize fd_set for select fd_set readfds; FD_ZERO(&readfds); // Initialize fd_set FD_SET(fd1, &readfds); // Add fd1 to readfds FD_SET(fd2, &readfds); // Add fd2 to readfds FD_SET(fd3, &readfds); // Add fd3 to readfds // Set timeout for select (e.g., 5 seconds) struct timeval timeout; timeout.tv_sec = 5; timeout.tv_usec = 0; // Call select. Wait for events int ret = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout); if (ret == -1) { perror("select failed"); return 1; } else if (ret == 0) { printf("Timeout occurred! No data available within 5 seconds.\n"); } else { // Check which file descriptor has a read event if (FD_ISSET(fd1, &readfds)) { printf("Data is available for reading on fd1 (STDIN)\n"); } if (FD_ISSET(fd2, &readfds)) { printf("Data is available for reading on fd2 (file2.txt)\n"); } if (FD_ISSET(fd3, &readfds)) { printf("Data is available for reading on fd3 (file3.txt)\n"); } } // Close file descriptors close(fd2); close(fd3); return 0; } Poll Compared to select, declared as a (fd, event, received) struct Lower performance than epoll, where the OS directly puts events in a queue. However, poll()’s struct is similarly used in epoll() Time complexity O(N) [N = number of registered events] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #include <stdio.h> #include <stdlib.h> #include <poll.h> #include <unistd.h> #include <fcntl.h> int main() { // Prepare file descriptors struct pollfd fds[2]; int timeout = 5000; // Wait 5 seconds // fd1: standard input fds[0].fd = STDIN_FILENO; fds[0].events = POLLIN; // Monitor for readable event // fd2: file (e.g., open file descriptor) int fd2 = open("example.txt", O_RDONLY); if (fd2 == -1) { perror("Failed to open file"); return 1; } fds[1].fd = fd2; fds[1].events = POLLIN; // Monitor for readable event // Call poll int ret = poll(fds, 2, timeout); if (ret == -1) { perror("poll failed"); return 1; } else if (ret == 0) { printf("Timeout! No events occurred within 5 seconds.\n"); } else { // Check events if (fds[0].revents & POLLIN) { // revents = returned events printf("Data is available on stdin.\n"); } if (fds[1].revents & POLLIN) { printf("Data is available in example.txt.\n"); } } // Close file descriptor close(fd2); return 0; } Epoll The OS directly registers events in the event queue, and the user program only monitors the event queue (blocking), maximizing efficiency Time complexity: Event queue: R/B tree. O(logn) for fd registration and deletion Event collection: O(1) or O(M) [M = number of occurred events] Note: When running Netty: Mac OS uses kqueue Linux uses epoll ...

June 2, 2025

Reactor Overview and Implementation

Reactor Table of Contents Purpose WebFlux provides developers with the Reactor interface to use Netty, so it is important to understand related concepts. What is Reactive Stream? A standardized interface for processing asynchronous streams using non-blocking back pressure. Reactor implements the reactive stream specification. https://www.reactive-streams.org/ Structure Traditional Observer Pattern Publisher Registers subscribers Delivers data to subscribers Subscriber Provides an update() callback function to execute logic, which is called by the publisher Similarity to Reactive Stream Interface ...

June 2, 2025

Structured Concurrency

Source jep480 (Java Enhancement Proposal) Original post introducing structured concurrency (2016) Summary of the jep480 document. Purpose of This Post Introduce a concurrency programming style that can eliminate common risks from cancellation and shutdown. Improve the observability of concurrent code. Motivation Developers manage complexity by dividing tasks into subtasks. In single-threaded code, subtasks are executed sequentially, but if subtasks are independent, running them concurrently can improve performance. However, managing many threads is very difficult. Unstructured concurrency with ExecutorService Example code using ExecutorService introduced in Java 5 for concurrency, showing what problems arise without structured concurrency. ...

June 2, 2025

Stub vs Mock

Purpose When developing, you may encounter the following concerns: Why are my tests breaking like this? Is this correct? Mocking this is so hard…! Why are there so many predefined states? How do I manage them? A good example to explain this is understanding the difference between stubs and mocks. This post explains that difference. Why? It helps explain integration and unit testing more clearly. Source: https://martinfowler.com/articles/mocksArentStubs.html Key Terms Test Double A general term for objects that pretend to be real objects for testing purposes. Types of test doubles include Dummy, Fake, Spies, Stubs, and Mocks. The term comes from “stunt double” in movies—think of someone performing dangerous actions in place of the actor. ...

June 2, 2025

When Constructor Use Cases

Content Summary of ‘when’ usage cases Source - Kotlin in Action What is ‘when’? A more powerful version of Java’s switch. Java switch Improves readability of if-else branching by using switch. However, branch arguments are limited to constants (mainly enums, strings). Kotlin when Branches can use not only constants (enums, strings) but also arbitrary objects and expressions—no restrictions. A universal branching statement. Use Cases 1. Branching on enums to return a specific string enum class 1 2 3 enum class Color { RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET } when code 1 2 3 4 5 6 7 8 9 10 fun getMnemonic(color: Color) = when (color) { Color.RED -> "Richard" Color.ORANGE -> "Of" Color.YELLOW -> "York" Color.GREEN -> "Gave" Color.BLUE -> "Battle" Color.INDIGO -> "In" Color.VIOLET -> "Vain" } No need for break; can use arrows With arrow functions in Java switch, this is now similar in Java Up to here, you might think “Isn’t this just like Java?” ...

June 2, 2025

Why CancellationException Should Be Rethrown

Reference It’s easier to understand if you think of a thread’s interrupt as a job’s cancel. When using runCatching, you must write code to rethrow the CancellationException. Kotlin does not provide a convenience method for this. - Related Issue Reason When a job is cancelled, it should not continue running. However, if you catch a CancellationException, the job may continue to run, so it is recommended to rethrow it. Problematic Code If you do not rethrow, a job that is already cancelled may continue to run. ...

June 2, 2025

Spring AOP Self-Invocation Problem and a Kotlinic Workaround

Spring AOP Problem In Spring, self-invocation refers to a method within a class calling another method of the same class. This can be problematic when using AOP (Aspect-Oriented Programming) annotations like @Transactional. Spring AOP is proxy-based. So if you call another method directly within the same class, it bypasses the proxy, and AOP annotations won’t be applied. For example, suppose you have method A annotated with @Transactional, and it’s called from method B in the same class. If method B calls A directly, Spring won’t manage the transaction properly because the call doesn’t go through the proxy. ...

May 27, 2024