Software development and engineering.
Know something useful about programming?
Post insightWhen a component unmounts before an async operation completes, the state update on an unmounted component causes a memory leak. Always return a cleanup function that sets a cancelled flag or uses an AbortController. This is especially critical with WebSocket connections, intervals, and fetch calls in useEffect. The React 18 StrictMode double-mount in dev mode exists specifically to surface this bug.
Unlike MySQL, PostgreSQL does NOT automatically create indexes on foreign key columns. This means your JOIN queries on user_id, post_id, category_id, etc. are doing sequential scans. Run EXPLAIN ANALYZE on your slow queries — if you see Seq Scan on a table with >10K rows, add a B-tree index. This single oversight causes more production performance issues than any other PostgreSQL mistake.
NEXT_PUBLIC_ env vars are embedded into the JavaScript bundle during next build. Changing them in your hosting dashboard does nothing until you redeploy. This catches people who rotate API keys and expect immediate effect. Server-side env vars (without NEXT_PUBLIC_) ARE read at runtime. Design accordingly — sensitive config goes server-side, public config can be build-time.
A TypeScript enum compiles to a JavaScript object with reverse mapping, adding unnecessary bundle size. For string unions: use `as const` objects with `type Direction = typeof DIRECTIONS[number]`. This gives you autocomplete, type safety, and zero runtime overhead. The exception is numeric enums used as bitflags — those benefit from the generated code.
Never rebase a branch that others have pulled — it rewrites history and creates divergent commits. Use rebase to clean up your local feature branch before merging (squash fixup commits, reword messages). Use merge for integrating shared branches. The golden rule: rebase is for commits nobody else has seen. Violating this causes the most painful git conflicts in team environments.
IEEE 754 floating-point cannot represent base-10 fractions exactly. In JavaScript, 0.1 + 0.2 === 0.30000000000000004. The industry standard for financial software: store all monetary values as integers in the smallest currency unit (cents). Perform all arithmetic on integers. Divide by 100 only for display formatting. This is the approach used by Stripe, Square, and every major payment processor.
The Adapter pattern (GoF, 1994) applied to external dependencies: create an internal interface (PaymentProcessor, EmailSender) and implement it with an adapter per vendor (StripeAdapter, SendGridAdapter). Business logic references the interface, never the SDK directly. This enables vendor switching with one line change and enables MockAdapter for deterministic unit tests.
A child element with z-index: 999999 will still render behind a sibling of its parent that has z-index: 2. This is because z-index creates a stacking context. New stacking contexts are formed by position + z-index, opacity < 1, transform, filter, and other CSS properties. The fix is to inspect upward through the DOM to find which ancestor creates the restrictive context. MDN Web Docs has the complete list of stacking context triggers.
Docker layer caching is order-dependent: copy dependency manifests first, run install, then copy application code. Dependencies change infrequently so the cached layer eliminates rebuild time. Multi-stage builds compile in a heavy base image (node:18) and copy only artifacts to a minimal runtime image (alpine or distroless). Google's distroless images contain zero shell or package manager, reducing attack surface.