Jun 13, 2026

[RACI]

The 4 RACI Roles

  • Responsible (The "Doer"): The person (or team) who actually performs the work to complete the task. They are hands-on and do the heavy lifting.
    Rule of thumb: There should be at least one 'R', but multiple contributors can share this responsibility.
  • Accountable (The "Owner"): The individual ultimately answerable for the correct and thorough completion of the deliverable. They delegate the work and sign off on the final result.
    Rule of thumb: There must be exactly one Accountable person per task to guarantee decision-making authority.
  • Consulted (The "Expert"): People who provide subject-matter expertise or input before a decision or action is finalized.
    Rule of thumb: Communication is two-way.
  • Informed (The "Loop"): People who need to be kept up-to-date on project progress, usually stakeholders or leadership.
    Rule of thumb: Communication is one-way—they are simply updated, not required to make decisions.

May 27, 2026

[C++] pointer arithmetic

Refernece:
[C++] Object Lifetimes reading minute
class Vec {
  public:
    double* data() { return &x; }

  private:
    double x,y,z;
};

Eigen::Map<...>(absl::Span<Vec>);

*(Vect::data() + 1) // Does not give us y

Take away: 

* Even though x, y, and z are allocated sequentially in memory without padding,
physical layout does not supersede semantic rules.
* The layout guarantees mean you can safely memcpy the data, or cast a Vec* to a double* to access the first element (x). It does not grant permission to use pointer arithmetic on double* to slide across the members.
* The pointer arithmetic is only guaranteed within the type of array.
* Pointer to variable only is considered as pointer to array of size 1.
* Thus any pointer arithmetic on single variable is considered out-of-bound; compiler is free to assume anything.

Explain:

Only char*, unsigned char*, and std::byte* are explicitly granted an exception in the standard to 
examine the raw object representation. double* enjoys no such privilege.

Fix:

class Vec {
 public:
  double* data() { return data_; } // Legal: returns pointer to element 0 of a 3-element array
 private:
  double data_[3]; // x=data_[0], y=data_[1], z=data_[2]
};

May 10, 2026

心胸格局 器大識深

職場上遇到值得學習的大老

實在是可遇不可求。

與智者同行,與強者為伍。

格局大的人在種樹,

格局小的人在砍樹。

格局大的人懂得長期投資,

願意合作共贏,把餅做大;

所以有些人身邊的貴人越來越多,

有些人身邊的人卻越來越少。

不是能力的差距,

而是格局的差距。

Apr 22, 2026

[C++] unaligned pointer convert to more strict alignment is an UB

Never create an unaligned pointer of the struct type.

Its UB to convert from one pointer with less alignment guarantees to another with more, if the underlying pointer is not aligned. 

Everything that happens after that is UB, including arithmetic. 


Reference:
https://eel.is/c++draft/expr.static.cast#12

Apr 20, 2026

[Rust] method resolution

Method Resolution and Borrowing

This is where the magic happens for your daily coding. When you call a method:

  1. Rust tries to find the method on the type itself.

  2. If it fails, it tries to dereference the type (*t) and looks again.

  3. If that fails, it tries to reference the type (&t) and looks again.



The Search Algorithm

Rust looks for a method named method by checking these categories in order:

1. Direct Match (Value and References)

First, it checks the type of the receiver (T) and its immediate references:

  • T (The type itself)

  • &T (Immutable reference)

  • &mut T (Mutable reference)

2. Deref Coercion (The "Unwrapping" Loop)

If no match is found, Rust uses the Deref trait to "unwrap" the type. If T implements Deref<Target = U>, it adds U to the search list and repeats step 1:

  • U

  • &U

  • &mut U

This continues recursively. If U derefs to V, it checks V, &V, &mut V. This is why you can call &str methods on a Box<String>.

3. Unsourced Coercion (Array to Slice)

If the type is an array [T; n], Rust will eventually attempt to coerce it into a slice [T].


The Three Transformation Rules

For every candidate type P found in the search above, Rust tries to match the method signature by attempting these three transformations in this exact order:

  1. Identity: receiver (The type matches exactly).

  2. Autoref: &receiver (Rust borrows it for you).

  3. Autoref-Mut: &mut receiver (Rust borrows it mutably).


Why the order matters

If a type has both an immutable foo(&self) and a mutable foo(&mut self), and you call it on a value, Rust will pick the immutable one first if it satisfies the call. This prevents accidental mutation.


Special Cases & Edge Cases

1. Shadowing (Inherent vs. Trait)

Rust has a strict hierarchy for where the method is defined:

  • Inherent Impls: Methods defined directly on the struct (impl MyStruct { ... }) always win.

  • Trait Impls: Methods from traits only count if the trait is in scope (use path::to::Trait).

  • Collision: If two traits in scope provide the same method name for the same type, the compiler throws an error, and you must use Fully Qualified Syntax: Trait::method(&receiver).

2. The "Dot" vs. "Function" Syntax

The auto-deref/autoref magic only happens with dot notation (a.b()).

If you use the associated function syntax (Type::method(a)), you must provide the exact type expected by the function signature. No coercion will help you there.