MisterMicheels Learning Notes

website·Indexed 32 days ago

https://learning-notes.mistermicheels.com/

A collection of technical notes and guides covering software engineering topics, including architecture design (Clean Architecture, Layered Architecture, Inversion of Control), data management (SQL, ACID, normalization), web technologies (CSS Flexbox, JavaScript event loop, TypeScript runtime type checking), and development processes (pair programming, feature flags, branch by abstraction).

Tokens
83.7K
Snippets
187
Records
511
Agent score
60%

What's inside MisterMicheels Learning Notes

  1. Overview of Java Date and Time API (java.time)

    Introduced in Java 8, the java.time API replaces the legacy Date and Calendar classes. Key characteristics include:

    • Immutability: All java.time objects are immutable; operations that modify a date or time return a new object.
    • Time Standard: A day is defined as exactly 86,400 seconds, with leap seconds handled by slightly adjusting the length of seconds.
  2. Overview of the C4 Model for software architecture

    The C4 model, created by Simon Brown, provides a hierarchical way to visualize software architecture to minimize the gap between diagrams and actual code. It is a simplified version of UML and the 4+1 architectural view model. It is notation-independent, meaning any diagramming tool can be used, though Structurizr is the dedicated tool for this model.
  3. Introduction to Java Streams

    Java Streams provide a declarative way to specify operations on lists and collections, focusing on what to do rather than how to do it. Unlike collections, streams do not necessarily store elements (they can be generated on demand or be infinite) and operations on a stream generate a new altered stream rather than modifying the original. Stream operations are lazy, meaning they are only executed when a terminal operation is invoked.
    // Imperative approach
    long numberLongWords = 0;
    for (String word: words) {
        if (word.length() > 3) {
            numberLongWords++;
        }
    }
    
    // Declarative Stream approach
    numberLongWords = words.stream()
            .filter(word -> word.length() > 3)
            .count();
  4. Overview of the Java Platform Module System (JPMS)

    Introduced in Java 9 (Project Jigsaw), the Java Platform Module System provides a high-level encapsulation layer above classes and packages. It allows developers to explicitly define which packages are exposed to other modules, reducing the JDK footprint (beneficial for IoT), improving maintainability through explicit dependencies, and enabling module-level deprecation. Unlike systems like OSGi, JPMS is supported directly by the Java compiler and virtual machine without relying on custom class loaders.
  5. Understand the core principles of refactoring

    Refactoring is a technique for restructuring existing code without changing its external behavior. It consists of a series of small, behavior-preserving transformations. Each individual transformation should be minimal and must leave the system in a working state. By applying many of these small changes sequentially, the overall structure of the code can be significantly improved while maintaining low risk and a short feedback loop.
  6. Combine different types of architectural boundaries

    Different types of boundaries (e.g., horizontal and vertical) can be used simultaneously at different levels of the architecture.

    Example: A system can be split into microservices using vertical slicing (functional areas), while each individual microservice employs a layered architecture using horizontal slicing to separate technical concerns (e.g., API layer vs. Data layer).

  7. Understand the CSS Flexbox model

    CSS Flexbox is used to layout items along a single direction (horizontal or vertical).

    • Flex Container: The parent element created by setting display: flex.
    • Flex Items: The direct children of the flex container; their size and position are managed by the flexbox model.
    • Main Axis: The primary direction of layout. It is horizontal if flex-direction: row is used, and vertical if flex-direction: column is used.
    • Cross Axis: The direction perpendicular to the main axis.

    Note: Flexbox is ideal for single-axis layouts. For layouts requiring both horizontal and vertical sizing control, CSS Grid is recommended.

  8. Make stable components flexible using the Open-Closed Principle

    To prevent a stable core business logic component from making the overall architecture inflexible, apply the Open-Closed Principle. This allows components to be extended without requiring modification of the existing source code. This can be achieved by:

    1. Defining interfaces or abstract classes instead of concrete implementations.
    2. Using Dependency Injection or the Strategy pattern to pass in different behavior-providing objects, where those objects adhere to interfaces defined within the stable component.
  9. Identify and avoid the Lasagna Architecture anti-pattern

    The 'Lasagna Architecture' (or architecture sinkhole anti-pattern) occurs when a system has too many layers, and a large percentage of requests simply pass through multiple layers without any meaningful logic being executed in those intermediate layers. This creates unnecessary complexity. A potential solution is to mark some of these intermediate layers as 'open' to allow bypassing.
  10. Resolve method signature conflicts in Java Interfaces (Diamond Problem)

    When a class implements multiple interfaces that provide the same method signature, Java requires the implementing class to be explicit about which implementation to use to avoid the 'diamond problem'.

    • Conflict Resolution: If two interfaces specify the same method signature, the implementing class must provide its own implementation, even if one of the interfaces provides a default implementation. You can delegate to a specific interface's default method using InterfaceName.super.methodName().
    • Class Priority: If a class inherits a method from a superclass and also implements an interface with a default method of the same signature, the superclass implementation always takes priority.
    public interface InterfaceA {
        public abstract void doSomething();
    }
    
    public interface InterfaceB {
        public default void doSomething() {
            System.out.println("test");
        };
    }
    
    public class Class implements InterfaceA, InterfaceB {
        // Compiler forces an implementation because of the conflict
        @Override
        public void doSomething() {
            // Delegate to the behavior specified in InterfaceB
            InterfaceB.super.doSomething();
        }
    }