Seamew Technical Blog

website·Indexed 29 days ago

https://seamew.top/

A collection of technical articles and tutorials covering Java development, Spring Framework (including Spring Boot and AOP), distributed systems like ZooKeeper and Kafka, algorithm design (Dynamic Programming, DFS, and Backtracking), and DevOps tools such as Docker and Linux (CentOS).

Tokens
41K
Snippets
170
Records
226
Agent score
47%

What's inside Seamew

  1. Find the largest number smaller than n using a specific set of digits

    Given a set of available digits (1-9) and a target number n, find the largest number that can be constructed using only those digits (with repetition allowed) such that the resulting number is strictly less than n.

    Examples:

    • Available digits: {1, 2, 9, 4}, n = 2533 $\rightarrow$ Result: 2499
    • Available digits: {1, 2, 5, 4}, n = 2543 $\rightarrow$ Result: 2542
    • Available digits: {1, 2, 5, 4}, n = 2541 $\rightarrow$ Result: 2525
    • Available digits: {1, 2, 9, 4}, n = 2111 $\rightarrow$ Result: 1999
    • Available digits: {5, 9}, n = 5555 $\rightarrow$ Result: 999
  2. Understand ZooKeeper ZAB Protocol and Operation Modes

    ZooKeeper relies on the ZAB (ZooKeeper Atomic Broadcast) protocol to ensure data synchronization across nodes. It operates in two primary modes:

    1. Recovery Mode (Leader Election): Triggered when the current leader node fails. The remaining nodes elect a new leader. Once elected, the cluster transitions to Broadcast Mode to synchronize data with the new leader.
    2. Broadcast Mode: The standard operational mode used to synchronize data across all nodes in the cluster.
  3. Understand ThreadLocal for thread-local variable storage

    ThreadLocal provides thread-local variables. It ensures that the accessed variable belongs to the current thread, with each thread maintaining its own independently initialized copy of the variable. This effectively provides thread isolation by binding variables to the specific thread, making it useful for passing data in multi-threaded environments without needing explicit synchronization.
  4. Understand AOP proxy creation via DefaultAdvisorAutoProxyCreator

    The DefaultAdvisorAutoProxyCreator class uses the postProcessBeforeInstantiation method to intercept bean creation. If a suitable TargetSource is found, it retrieves the necessary advices and advisors for the bean and uses a ProxyFactory to create a proxy object. This process effectively 'short-circuits' the standard bean instantiation process, returning the proxy object directly.
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
      TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
      if (targetSource != null) {
        // ...
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
        // Create proxy via ProxyFactory
        Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
        return proxy;
      }
      return null;
    }
  5. Understand Kafka Transactional Guarantees

    Kafka transactions provide atomicity across multiple operations, ensuring that a set of actions—specifically consuming messages, producing messages, and committing consumer offsets—either all succeed or all fail. Transactions rely on the Idempotent Producer; enabling transactions automatically enables idempotency.
  6. Understand Spring's Three-Level Cache for Circular Dependencies

    Spring uses three internal Map collections to manage Bean states during the creation process to resolve circular dependencies (e.g., Bean A depends on Bean B, and Bean B depends on Bean A).

    • First-Level Cache (singletonObjects): Stores fully initialized Beans that are ready for use.
    • Second-Level Cache (earlySingletonObjects): Stores 'half-finished' Beans—objects that have been instantiated but have not yet had their properties set or initialization completed.
    • Third-Level Cache (singletonFactories): Stores ObjectFactory (lambda expressions). These factories can produce an early reference to a Bean (either a raw half-finished Bean or a proxy Bean). This is critical for handling AOP proxies during circular dependencies.
    // First-level: Complete Beans
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
    
    // Second-level: Half-finished Beans
    private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
    
    // Third-level: Bean factories (lambdas)
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
  7. Reference ZooKeeper Stat attributes

    The Stat object provides metadata about a ZooKeeper node:
    AttributeDescription
    cZxidTransaction ID when the node was created
    ctimeTime when the node was created
    mZxidTransaction ID of the last update to the node
    mtimeTime of the last update to the node
    pZxidTransaction ID of the last change to the node's children list
    cversionVersion number of the child nodes
    dataVersionVersion number of the node's data
    aclVersionVersion number of the node's ACL
    ephemeralOwnerSessionID of the creator if ephemeral; 0 if persistent
    dataLengthLength of the data content
    numChildrenCurrent number of child nodes
  8. Understand ZooKeeper's ZAB (ZooKeeper Atomic Broadcast) Protocol

    ZooKeeper uses the ZAB protocol to ensure data synchronization across nodes. It operates in two primary modes:

    1. Recovery Mode (Leader Election): Triggered when the leader node fails. The remaining nodes elect a new leader, which then transitions the cluster into broadcast mode.
    2. Broadcast Mode: Used to synchronize data across all nodes once a leader is established.
  9. Reference ZooKeeper Stat properties

    The Stat object provides metadata about a ZooKeeper node:
    PropertyDescription
    cZxidTransaction ID when the node was created
    ctimeCreation time of the node
    mZxidTransaction ID of the last update to the node
    mtimeTime of the last update to the node
    pZxidTransaction ID of the last change to the node's children list
    cversionVersion number of the child nodes
    dataVersionVersion number of the node's data
    aclVersionVersion number of the node's ACL
    ephemeralOwnerSessionID of the creator if ephemeral; 0 if persistent
    dataLengthLength of the data content
    numChildrenCurrent number of child nodes
  10. Understand the relationship between Backtracking and Depth-First Search (DFS)

    Backtracking and Depth-First Search (DFS) are complementary techniques. Both are concrete implementations of the recursive thought process, where the algorithm explores as far as possible along each branch before backtracking to the previous node to try different paths.
  11. Understand the role of DefaultAdvisorAutoProxyCreator in Spring AOP

    The DefaultAdvisorAutoProxyCreator class is responsible for creating proxy objects for beans that meet specific requirements. It primarily utilizes the postProcessBeforeInstantiation method to intercept bean creation. If a suitable TargetSource is found, it retrieves the necessary advices and advisors for the bean and uses a ProxyFactory to create the proxy object, effectively short-circuiting the standard instantiation process.
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
      TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
      if (targetSource != null) {
        if (StringUtils.hasLength(beanName)) {
          this.targetSourcedBeans.add(beanName);
        }
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
        // Create proxy via ProxyFactory
        Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
      }
      return null;
    }
  12. Find the largest number smaller than n using a specific set of digits

    Given a set of available digits A (containing numbers from 1-9) and a target number n, find the largest number that can be constructed using digits from A that is strictly less than n. Digits from A can be reused multiple times.

    Examples:

    • A={1, 2, 9, 4}, n=2533 → Result: 2499
    • A={1, 2, 5, 4}, n=2543 → Result: 2542
    • A={1, 2, 5, 4}, n=2541 → Result: 2525
    • A={1, 2, 9, 4}, n=2111 → Result: 1999
    • A={5, 9}, n=5555 → Result: 999