Read env var with a default
GoFall back when the var is unset or blank, so an empty string never silently wins.
func getEnv(key, fallback string) string {
if v := strings.TrimSpace(os.Getenv(key)); v != "" {
return v
}
return fallback
}
Snippets you reach for again and again, grouped by language, one click to copy. Comments are in English so they drop into any project as-is.
Fall back when the var is unset or blank, so an empty string never silently wins.
func getEnv(key, fallback string) string {
if v := strings.TrimSpace(os.Getenv(key)); v != "" {
return v
}
return fallback
}
On timeout or cancellation Do returns an error and resp is nil — return early, never dereference resp.
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err // timeout/cancel: context.DeadlineExceeded / Canceled
}
defer resp.Body.Close()
WaitGroup joins every goroutine, a mutex collects each error, errors.Join merges them (Go 1.20+).
var (
wg sync.WaitGroup
mu sync.Mutex
errs []error
)
for _, u := range urls {
wg.Add(1)
go func(u string) {
defer wg.Done()
if _, err := fetch(u); err != nil {
mu.Lock()
errs = append(errs, err)
mu.Unlock()
}
}(u)
}
wg.Wait()
return errors.Join(errs...)
Scanner stops silently on lines over 64 KB by default — raise the cap with Buffer and always check sc.Err().
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
sc := bufio.NewScanner(f)
sc.Buffer(make([]byte, 0, 64*1024), 1024*1024) // raise the per-line cap to 1 MB
for sc.Scan() {
line := sc.Text()
_ = line
}
return sc.Err() // long lines surface here: bufio.Scanner: token too long
Decoding configs or API payloads with it makes a misspelled field fail loudly instead of vanishing.
dec := json.NewDecoder(resp.Body)
dec.DisallowUnknownFields() // a misspelled field now fails loudly
var cfg Config
if err := dec.Decode(&cfg); err != nil {
return err
}
NewTicker without Stop leaks the runtime timer; a done channel lets the loop exit.
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
// runs every second
case <-done:
return
}
}
atomic.Int64 (Go 1.19+) is lighter than mutex + int64 and impossible to forget to lock.
var hits atomic.Int64
hits.Add(1)
total := hits.Load()
At boundaries that may panic, a named return plus deferred recover turns a crash into a handleable error.
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
}
}()
dict.fromkeys dedupes while preserving order; set scrambles it and a manual loop is slower.
def dedupe(items):
return list(dict.fromkeys(items))
Sort items by value with a key lambda; reverse=True gives the top 10 most frequent.
top = sorted(counter.items(), key=lambda kv: kv[1], reverse=True)[:10]
Mount a retrying HTTPAdapter on a Session. timeout must be a tuple — a bare number only bounds the read.
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
session = requests.Session()
session.mount("https://", HTTPAdapter(max_retries=Retry(
total=3, backoff_factor=0.5,
status_forcelist=[429, 500, 502, 503, 504],
)))
resp = session.get(url, timeout=(3, 10)) # (connect timeout, read timeout)
Naive now() is local wall time and drifts across deployments; pin the zone with zoneinfo (3.9+).
from datetime import datetime
from zoneinfo import ZoneInfo
now = datetime.now(ZoneInfo("Asia/Shanghai"))
pathlib's rglob matches recursively; pair with stat().st_mtime to sort by modification time.
from pathlib import Path
logs = sorted(Path("var/log").rglob("*.log"), key=lambda p: p.stat().st_mtime)
Number from 1 and zero-pad with :03d so names sort correctly; sort first for reproducible runs.
from pathlib import Path
for i, p in enumerate(sorted(Path("photos").glob("*.jpg")), 1):
p.rename(p.with_name(f"photo-{i:03d}.jpg"))
Field defaults must be immutable; use default_factory for lists/dicts or Python raises ValueError.
from dataclasses import dataclass, field
@dataclass
class Cart:
items: list = field(default_factory=list) # not items: list = []
perf_counter is monotonic and immune to clock adjustments; finally prints even on exceptions.
from contextlib import contextmanager
from time import perf_counter
@contextmanager
def timer(label):
start = perf_counter()
try:
yield
finally:
print(f"{label}: {perf_counter() - start:.3f}s")
with timer("query"):
run_query()
structuredClone handles Date, Map, Set and circular refs — no library needed.
const copy = structuredClone(obj);
Fires after ms of quiet — ideal for search inputs; switch to a leading variant if the first keystroke must respond.
function debounce(fn, ms = 300) {
let t;
return (...args) => {
clearTimeout(t);
t = setTimeout(() => fn(...args), ms);
};
}
Exponential backoff (delay × 2^i); only rethrows on the final attempt.
async function retry(fn, times = 3, delay = 500) {
for (let i = 0; i < times; i++) {
try {
return await fn();
} catch (e) {
if (i === times - 1) throw e;
await new Promise((r) => setTimeout(r, delay * 2 ** i));
}
}
}
AbortSignal.timeout is one line; it needs Safari 16.4+ /Node 17.3+ — fall back to AbortController + setTimeout.
const resp = await fetch(url, { signal: AbortSignal.timeout(5000) });
get returns null when missing — default it with ??; Number(null) is 0 and hides bugs.
const params = new URLSearchParams(location.search);
const page = Number(params.get("page") ?? 1);
Build all chunks up front — safer than splicing the original array in place.
const chunk = (arr, size) =>
Array.from({ length: Math.ceil(arr.length / size) }, (_, i) =>
arr.slice(i * size, i * size + size));
Cleaner than setInterval for poll-style waits; use an AbortSignal variant when cancellation must interrupt it.
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
await sleep(1000);
One line with Set; NaN dedupes correctly, objects dedupe by reference.
const uniq = [...new Set(arr)];
-e exits on error, -u on unset vars, pipefail surfaces mid-pipeline failures; reset IFS so spaces don't split words.
set -euo pipefail
IFS=$'\n\t'
-print0 with read -d '' splits on NUL, so spaces and newlines in filenames stay intact.
find . -name '*.log' -print0 | while IFS= read -r -d '' f; do
gzip "$f"
done
getopts is a POSIX builtin — the safest way to parse short options; finish with shift to drop what was consumed.
while getopts "f:v" opt; do
case "$opt" in
f) file="$OPTARG" ;;
v) verbose=1 ;;
*) echo "usage: $0 [-f file] [-v]" >&2; exit 1 ;;
esac
done
shift $((OPTIND - 1))
macOS sed -i requires a suffix argument; copying the Linux form verbatim fails with an undefined-variable error.
# GNU sed (Linux)
sed -i 's/foo/bar/g' file.txt
# BSD sed (macOS): empty suffix = no backup
sed -i '' 's/foo/bar/g' file.txt
-P sets parallelism (nproc for cores) and -I{} builds one command per item — good for CPU-bound jobs.
ls *.jpg | xargs -P "$(nproc)" -I{} convert {} -resize 800x {}.webp
mktemp -d creates a unique dir; trap on EXIT cleans it on every exit path.
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
lsof -i :port lists the owning process; on slim containers without lsof, use ss instead.
lsof -i :8080 # macOS / Linux
ss -tlnp | grep 8080 # Linux fallback when lsof is missing
nohup + & detaches from the terminal; >> appends and 2>&1 merges stderr — always save the PID.
nohup ./worker >> worker.log 2>&1 &
echo $! > worker.pid
OFFSET slows with depth; compare the last row of the previous page as a cursor so the index is used.
SELECT id, title FROM posts
WHERE (created_at, id) < (:cursor_at, :cursor_id)
ORDER BY created_at DESC, id DESC
LIMIT 20;
ROW_NUMBER per partition with rn = 1 beats group-by-then-self-join in clarity and speed.
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (
PARTITION BY user_id ORDER BY created_at DESC
) AS rn
FROM orders
) t WHERE rn = 1;
ON CONFLICT is PostgreSQL/SQLite; MySQL spells it ON DUPLICATE KEY UPDATE.
INSERT INTO stats (day, views) VALUES (DATE '2026-10-15', 1)
ON CONFLICT (day) DO UPDATE SET views = stats.views + 1;
An anchor (roots) plus a recursive term joining the previous level; a missing termination condition loops forever.
WITH RECURSIVE tree AS (
SELECT id, parent_id, name, 0 AS depth
FROM categories WHERE parent_id IS NULL
UNION ALL
SELECT c.id, c.parent_id, c.name, t.depth + 1
FROM categories c JOIN tree t ON c.parent_id = t.id
)
SELECT * FROM tree ORDER BY depth, name;
The default frame is UNBOUNDED PRECEDING → CURRENT ROW; write it out so readers don't have to guess.
SELECT day, views,
SUM(views) OVER (
ORDER BY day
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS total
FROM daily_views;
date_trunc snaps timestamps to month/week/day; GROUP BY 1 references the first column by position.
SELECT date_trunc('month', created_at) AS month, COUNT(*)
FROM orders
GROUP BY 1 ORDER BY 1;
SUM(...) OVER () with an empty frame is the grand total; cast to numeric first or integer division truncates.
SELECT category, amount,
amount::numeric / SUM(amount) OVER () AS share
FROM sales;
Run it before adding a unique index — existing duplicates make the creation fail.
SELECT email, COUNT(*) FROM users
GROUP BY email
HAVING COUNT(*) > 1;
reset --mixed is local-only; once pushed and possibly pulled, use revert instead.
git reset --mixed HEAD~1 # changes back to worktree, commit gone
# if pushed and possibly pulled, revert instead:
git revert HEAD
--amend rewrites the latest commit; amending a pushed one needs a force push — confirm nobody has built on it.
git commit --amend -m "a more accurate commit message"
# include the file you forgot
git add forgotten.txt && git commit --amend --no-edit
-p stages hunk by hunk, splitting two changes in one file into separate commits.
git add -p # interactive hunk-by-hunk staging
git add -p path.txt # only this file
Binary search cuts N investigations to log₂N; when a script can decide, git bisect run automates it.
git bisect start
git bisect bad # HEAD is bad
git bisect good v1.2.0 # this tag is good
# git checks out candidates; just mark good/bad, then:
git bisect reset
--merged lists only merged branches; grep excludes the current and main branches, and -d refuses unmerged ones.
git branch --merged main | grep -v '^\*\|main' | xargs -r git branch -d
After committing secrets: rewrite, force push AND rotate the key. Use filter-repo, not the deprecated filter-branch.
git filter-repo --path secrets.env --invert-paths
# then force push; rotate the key - rewriting != un-leaking
No matching snippets — try another keyword or language
The snippets you reach for again and again, in six groups: Go, Python, JavaScript, Shell, SQL and Git - 46 in total. Each one is the smallest complete answer to a concrete problem, not a syntax gallery.
Every code block has a copy button in its top-right corner; language tabs filter the list and the search box matches titles, descriptions and code. All content is baked into the page at build time, so it stays fully readable with JavaScript disabled.
Yes. They apply standard-library or idiomatic techniques, depend on no particular framework and carry no license restrictions - copy them and adjust the naming to taste. Still run them against your own edge cases first: a snippet solves a common problem, it does not replace your tests.
This page ships in Chinese and English. Chinese comments would mean maintaining two copies of every snippet, and any missed edit shows readers a half-translated mess; English comments avoid that at the source and work in projects of either language.
Yes. Rust, Java, C# and Kotlin are on the list, prioritised by what readers of this site actually use. You can nominate a language or a specific snippet via the feedback button.
The page header shows the last update. Entries affected by a new language release (Go, Python, ...) are revised afterwards, and better approaches are folded in as they are found.