DevOps Lounge

Core developer skills

The skills every developer leans on, whatever the stack: version control, the terminal, containers, databases, testing, security and the career side of the job.

Git 7

  • Git Mistake First Aid: Plain-English Recovery Recipes

    A short, no-jargon page of recipes for the Git situations that make people panic: committed to the wrong branch, a bad commit message, an undo that went too far. Bookmark it, then read the explanations so the fix stops feeling like magic.

    dangitgit.comGitBeginner
  • Atlassian Git Tutorials: Workflows, Merging and Rewriting History

    Free, well-illustrated tutorials that go beyond commit and push: branching workflows, merge versus rebase, undoing changes and rewriting history. A good second Git resource once the basics are comfortable and you start working in a team.

    atlassian.comGitBeginner
  • Undo the Undo: Recovering Lost Commits With git reflog

    Git rarely deletes work right away. Every time HEAD or a branch tip moves, the reflog records where it was, so a botched reset or rebase is usually recoverable. Read entries like HEAD@{3} as "where HEAD was three moves ago". Create a branch from the right one before doing anything else, because a branch name is what keeps commits safe from cleanup. Two limits worth knowing: the reflog is local to your clone, and entries expire. By default unreachable ones are pruned after about 30 days and reachable ones after about 90, controlled by gc.reflogExpire and gc.reflogExpireUnreachable. So recover soon, and never rely on it as a backup.

    git-scm.comGitIntermediate
  • Challenge: Rescue a Branch You Just Deleted

    Ten minutes, a scratch repo, no risk. Prove to yourself that a deleted branch is not gone. Now recover it: 1. Run git reflog and find the "add payments" commit. 2. Run git branch feature/payments <sha> with that hash. 3. Check with git log feature/payments --oneline and confirm pay.txt exists after switching. Stretch goal: repeat the exercise, but this time lose the commit by running git reset --hard HEAD~1 on the branch itself, and recover it the same way. Notice that the capital D in -D only means "delete even if unmerged"; the commits stay in the object store until garbage collection removes them.

    git-scm.comGitBeginner
  • Interactive Rebase: Tidy a Branch Before Asking for Review

    A reviewer reads your history as a story, so make it readable. Interactive rebase lets you reshape local commits before they are shared. In the editor, change the word at the start of a line: - reword to fix a message - squash or fixup to fold a commit into the one above it - drop to remove it, and reorder lines to reorder commits A neat habit: when you spot a fix for an earlier commit, record it with git commit --fixup <sha>, then later run git rebase -i --autosquash origin/main and Git arranges the fixup commits for you. Rewriting changes commit hashes, so only do it on commits nobody else has based work on. If you must update a branch you already pushed, prefer git push --force-with-lease over --force, because it refuses to overwrite commits you have not seen. If the rebase goes wrong, git rebase --abort restores where you started.

    git-scm.comGitIntermediate
  • Find the Commit That Broke It: Automated git bisect

    When a regression appeared "sometime in the last 200 commits", binary search beats reading diffs. Git bisect halves the range each step, so even a few hundred commits take around eight checks. The script passed to run decides the verdict by exit code: 0 means good, 1 to 127 (except 125) means bad, and 125 means "cannot test this commit, skip it". A script can be as small as a single test command, for example npm test -- -t "login" or a curl that fails on a bad status. Tips: keep the script outside the repository tree or untracked so checkouts do not remove it, and make sure the build step is inside the script. Finish with git bisect reset to return to your branch.

    git-scm.comGitIntermediate
  • Scrub a Leaked File From History With git filter-repo

    If a credentials file or a huge binary landed in history, deleting it in a new commit does not remove it from old ones. The maintained tool for rewriting history is git filter-repo, which the Git project itself points to in place of filter-branch. Notes: - It insists on a fresh clone as a safety check, so work on a copy. - Every commit after the file's first appearance gets a new hash, so every collaborator must re-clone or carefully reset, and open pull requests will need attention. - Forks, caches and CI logs may still hold the old data, and hosting platforms can keep unreachable commits for a while. The key point for secrets: assume they are compromised the moment they are pushed. Rotate the credential first; the history rewrite is cleanup, not remediation.

    github.comGitAdvanced

Linux 7

  • Linux Journey: A Gentle Path From First Command to Confident User

    Free lessons in small chunks covering the command line, users and permissions, processes, networking and more. Start here if the terminal still feels foreign, and use the quizzes to check what actually stuck before moving on.

    linuxjourney.comLinuxBeginner
  • explainshell: Paste a Command, See What Every Part Means

    Paste any shell command and each flag and argument is matched to the relevant excerpt from its manual page. Handy for decoding a copied one-liner before you run it, and for learning how pipes and options fit together.

    explainshell.comLinuxBeginner
  • BashPitfalls: The Shell Mistakes Everyone Makes Once

    A catalogue of common Bash bugs, each with a short explanation and a safer pattern: unquoted variables, parsing ls output, misuse of test. Read it before writing scripts that will run unattended, then run ShellCheck on what you have.

    mywiki.wooledge.orgLinuxIntermediate
  • Challenge: Find What Is Filling the Disk in Five Minutes

    A full disk takes services down quietly, so practice the hunt before you need it. 1. Check which filesystem is full: df -h 2. Check inodes too, since many tiny files can exhaust them with space to spare: df -i 3. Descend one level at a time: Repeat on the largest directory until you reach the culprit. The -x flag keeps du on one filesystem, and sort -h understands sizes like 4.0K and 2.1G. Your task: run this on your own machine or a VM, write down the three biggest directories under /var, and explain what each one is for. Bonus: a deleted file that a process still holds open keeps using space. Look for it with sudo lsof +L1, which lists open files whose link count is zero.

    man7.orgLinuxBeginner
  • Inspect a Running Process Through /proc

    Linux exposes live process state as files, so you can answer many "what is this thing doing?" questions with cat and ls, even on a minimal container image without extra tools. The command line is NUL-separated, hence the tr. A growing count in fd points to a descriptor leak, and Max open files in limits tells you how close you are to the ceiling. VmRSS is resident memory. You can read your own processes freely; other users' details need root. The manual page above documents every file, and is worth skimming once for maps, smaps and environ.

    man7.orgLinuxIntermediate
  • Make Bash Scripts Fail Loudly: set -euo pipefail Explained

    A script that keeps going after an error can do real damage. A common opening is: - -e exits when a command fails - -u treats an unset variable as an error, catching typos like $DIR_NAEM - -o pipefail makes a pipeline fail if any stage fails, not just the last Know the limits. -e is ignored in places such as an if condition or the left side of && and ||, and in a few subshell cases, so it is a safety net, not a substitute for checking results you care about. Tolerate an expected failure explicitly: grep -q foo file || true. Also quote your variables, and run ShellCheck. The manual page linked here lists every option precisely, including the exceptions to -e.

    gnu.orgLinuxIntermediate
  • Trace a Hung Process With strace

    When a process is stuck and the logs are silent, strace shows what it asks the kernel to do. A blocked read on a socket, a connect to the wrong address, or endless open failures all stand out. Meaning of the flags: -f follows child threads and processes, -tt adds timestamps, -T shows time spent inside each call, -s lengthens printed strings, and -o writes to a file. Filtering with -e trace= cuts the noise. Read the last lines first: if the final line is a call that has not returned, that is where it is stuck. Expect a slowdown while tracing, and attaching may need root or relaxed ptrace settings. Avoid tracing a busy production process for long.

    man7.orgLinuxAdvanced

SQL 5

  • Use The Index, Luke: A Free Book on SQL Indexing

    A free online guide to how database indexes work and how to design them for real queries. It covers the anatomy of an index, the WHERE clause, sorting and joins. Read it when queries are slow and you want to understand why.

    use-the-index-luke.comSQLIntermediate
  • PostgreSQL Exercises: Practice SQL Against a Real Database

    Graded SQL exercises on a small club-membership schema, running in the browser with hints and worked answers. Moves from simple selects to joins, aggregates and window functions, so it is a good place to practice after a first course.

    pgexercises.comSQLBeginner
  • Read a Postgres Query Plan Without Guessing

    The plan tells you what the database did, so you can stop guessing at indexes. What to look for: - The scan type: Seq Scan reads the whole table, Index Scan and Bitmap Heap Scan use an index. - Estimated versus actual rows. A big gap means stale statistics (run ANALYZE) or a misleading predicate. - Rows Removed by Filter: many rows read and thrown away suggests a missing or wrong index. - Timing is per node and may be multiplied by the loop count. Important: ANALYZE really executes the statement. For writes, wrap it: BEGIN; EXPLAIN ANALYZE UPDATE ...; ROLLBACK;. And a sequential scan on a small table is often the right choice, so judge by timing, not by the node name alone.

    postgresql.orgSQLIntermediate
  • Challenge: Fix a Slow Query With the Right Composite Index

    Build a million-row table, watch a query struggle, then fix it. About twenty minutes in PostgreSQL. Compare the plans and timings. The index lets the database jump to one customer and read rows already in date order, so no sorting is needed. Then experiment: drop it and create (created_at, customer_id) instead. Why is the first query worse now? Multicolumn B-tree indexes are most useful when the query constrains the leading columns, so put equality columns first, then the sort or range column.

    postgresql.orgSQLIntermediate
  • Isolation Levels in Plain Terms: Pick One on Purpose

    Transactions are not automatically safe from each other. In PostgreSQL the default is Read Committed: each statement sees data committed before it started, so two reads in one transaction can differ. A classic bug is read-modify-write: Your options, roughly from lightest to strongest: an atomic UPDATE like the one above, SELECT ... FOR UPDATE to lock the row, or a stricter level such as Repeatable Read or Serializable. The catch with the strict levels: the database may abort a transaction with a serialization failure (SQLSTATE 40001), and your code must retry the whole transaction. In PostgreSQL, Read Uncommitted behaves like Read Committed. Other databases differ, so check yours.

    postgresql.orgSQLAdvanced

APIs 5

  • Learn OpenAPI: The Official Introduction to Describing APIs

    The official learning site from the OpenAPI Initiative explains how to describe an HTTP API in a machine-readable contract. Start here before generating docs, mocks or client code, so the spec becomes the shared source of truth for the team.

    learn.openapis.orgAPIsBeginner
  • Microsoft Web API Design Best Practices: A Practical Checklist

    A thorough guide to designing HTTP APIs: resource naming, methods and status codes, pagination, versioning and async operations. Useful as a review checklist for a new API, whatever stack or cloud you build on.

    learn.microsoft.comAPIsIntermediate
  • Idempotency Keys: Make Retried POST Requests Safe

    Networks drop responses, not just requests. If a client retries a payment after a timeout, you must not charge twice. The standard fix is a client-generated idempotency key. Stripe documents a good reference design: the client sends an Idempotency-Key header with a random value such as a UUID (their keys can be up to 255 characters), and the server stores the first result and replays it for retries. Reusing a key with different parameters is rejected. A minimal server-side shape: 1. Insert the key before doing work. A unique violation means it is a retry or a concurrent duplicate. 2. If the stored hash differs from this request, return an error. 3. Run the operation and save the response in the same transaction where possible. 4. Expire old keys; Stripe prunes after at least 24 hours. GET and DELETE are already idempotent by definition, so keys matter mainly for POST.

    docs.stripe.comAPIsIntermediate
  • Challenge: Replace Offset Pagination With a Keyset Cursor

    OFFSET pagination gets slower the deeper you go, and it can skip or repeat rows when data changes between pages. Keyset pagination fixes both. Try it in thirty minutes on any SQL database with a table of a few hundred thousand rows. Page one: Next page, using the last row you returned: Steps: 1. Create an index on (created_at, id). 2. Compare EXPLAIN output for this query against OFFSET 100000. 3. Encode (created_at, id) as an opaque base64 string and return it as next_cursor in your API response. The tie-breaker id matters because timestamps repeat. The trade-off: you lose jump-to-page-N, which is usually fine for feeds and exports.

    use-the-index-luke.comAPIsIntermediate
  • Change an API Without Breaking Anyone: Compatibility Rules

    Clients you do not control will depend on every detail you expose. Google's API improvement proposal on backwards compatibility spells out what is safe within one major version. Generally safe: adding new methods, new response fields, and optional request fields whose default preserves old behavior. Adding enum values to responses is allowed but risky, since clients may not handle unknown values, so document it. Breaking: removing anything, renaming (which is removal plus addition), changing a field's type, changing a default, changing a value's format, or tightening semantics that clients rely on. Habits that follow: - Make new request fields optional. - Tell clients to ignore unknown response fields and handle unknown enum values. - To rename, add the new name, keep the old one, deprecate it publicly, and remove it only in a new major version. - Review diffs of your OpenAPI file in CI to catch accidental breaks. When a break is truly necessary, version it and give people time to migrate.

    google.aip.devAPIsAdvanced

Docker 4

  • Docker Build Best Practices: Smaller, Faster, Safer Images

    The official guidance on writing Dockerfiles: choosing base images, multi-stage builds, layer caching, pinning and cleanup. Use it as a review checklist the next time an image feels bloated or a build keeps missing the cache.

    docs.docker.comDockerIntermediate
  • iximiuz Labs: Hands-On Container and Linux Playgrounds

    Browser-based playgrounds and challenges for containers, Linux internals and Kubernetes, with a number of free ones. Good for building a real mental model of what a container is, by poking at namespaces and cgroups yourself.

    labs.iximiuz.comDockerIntermediate
  • Multi-Stage Docker Builds: Ship the Binary, Not the Toolchain

    Build tools, caches and source code have no business in your runtime image. A multi-stage build compiles in one stage and copies only the result into a small final one. Results: a much smaller image, a smaller attack surface, and faster pulls. Copying the dependency files before the source keeps the download layer cached until they change. Caveats: scratch has no shell, CA certificates or timezone data, so copy those in or choose a minimal base such as a distroless one if you need them. Interpreted languages follow the same idea: install dependencies in a builder stage and copy the prepared directory over. You can also stop at a stage with docker build --target build . to debug it.

    docs.docker.comDockerIntermediate
  • Challenge: Lock Down a Container and Prove It Worked

    Run a container with fewer privileges, then verify each restriction yourself. Needs Docker and about fifteen minutes. Inside the container, test: 1. id should show uid 10001, not root. 2. touch /x should fail with a read-only filesystem error, while touch /tmp/x succeeds. 3. grep CapEff /proc/self/status should show all zeros, meaning no effective capabilities. Now loosen one flag at a time and notice what changes. Then ask the harder question for your own service: which flags does it actually need, and what breaks when you remove the rest? Put the result into a Compose file or Kubernetes security context so it is repeatable. Never use --privileged as a shortcut to make an error disappear.

    docs.docker.comDockerIntermediate

System Design 4

  • System Design Primer: A Map of Scaling Concepts and Trade-offs

    A large open-source study guide covering load balancers, caching, databases, queues and consistency, with diagrams and example designs. Use it to build vocabulary and a mental catalogue of trade-offs before design discussions or interviews.

    github.comSystem DesignIntermediate
  • Amazon Builders Library: How Large Systems Fail and Recover

    Articles by Amazon engineers on operating distributed systems, including timeouts, retries with backoff and jitter, and avoiding overload. Read them when you design for failure and want the reasoning behind patterns, not only the names.

    aws.amazon.comSystem DesignAdvanced
  • Cache-Aside Done Right: TTLs, Invalidation and Stampedes

    Cache-aside is the usual pattern: the application checks the cache, falls back to the database on a miss, and fills the cache itself. Points to get right: - Always set a TTL, so mistakes eventually heal. Add jitter so many keys do not expire together. - On writes, update the database first and then delete the key. Deleting is simpler than rewriting. - A hot key expiring can send many requests to the database at once. Let one request rebuild it while the others wait or serve slightly stale data. - Decide whether caching "not found" is worth it, with a short TTL. Remember the cache is an optimization; the system must still work, slowly, without it.

    learn.microsoft.comSystem DesignIntermediate
  • At-Least-Once Queues Need Idempotent Consumers

    Most queues promise at-least-once delivery. A message can arrive twice, so a consumer that is not safe to repeat will eventually bill someone twice. Take SQS as a concrete example. A received message becomes invisible for the visibility timeout (default 30 seconds). If you do not delete it in time, it reappears and another consumer may process it. You can extend it with ChangeMessageVisibility, up to a 12-hour total limit. Safe consumer recipe: 1. Pick a stable id: the message id or, better, a business id such as an order number. 2. In one database transaction, insert that id into a processed table with a unique constraint and apply the effect. 3. If the insert conflicts, skip the work. 4. Delete the message only after the transaction commits. 5. Set the timeout above your typical processing time, and configure a dead-letter queue so poison messages stop looping. Alert on dead-letter queue depth and on message age, since those show trouble before users do.

    docs.aws.amazon.comSystem DesignAdvanced

Testing 4

  • The Practical Test Pyramid: Deciding What to Test Where

    A long, example-driven article on balancing unit, integration, contract and end-to-end tests. Read it when your suite is slow or flaky, or when you cannot decide at which level a new test belongs.

    martinfowler.comTestingIntermediate
  • Software Engineering at Google: The Testing Overview Chapter

    A free chapter on why tests matter at scale, how test size relates to speed and reliability, and what makes tests maintainable. A good grounding for arguing about test strategy with evidence rather than taste.

    abseil.ioTestingIntermediate
  • Challenge: Test Your Code With Properties, Not Just Examples

    Example-based tests check what you thought of. Property-based tests check rules and let the library hunt for counterexamples. Try it in twenty minutes with Python. Run pytest. Now pick a function of your own and write a round-trip property, such as decode(encode(x)) == x. When a property fails, Hypothesis shrinks the input to a small failing example, which is often the real lesson. If it fails on something you consider invalid input, tighten the strategy and write down the assumption. Good property candidates: round trips, idempotence, "output is never longer than input", and comparing a fast implementation to a simple one.

    hypothesis.readthedocs.ioTestingIntermediate
  • Test Behavior, Not Implementation: Guiding Principles for UI Tests

    Tests that break on every refactor teach teams to ignore them. The Testing Library project argues for tests that resemble how people use the software, because that is where confidence comes from. Practical consequences, in any stack: - Query elements the way a user finds them: by role, label or visible text, not by CSS class or internal component names. - Assert on outcomes a user can see, such as a message appearing, not on state variables or method calls. - Avoid testing private helpers directly. If a refactor changes internals but not behavior, the test should still pass. - Mock at the network boundary, not inside your own modules. A quick self-check for any test: if I rename an internal function, does it fail? If yes, it is coupled to implementation. If I break the feature, does it fail? If no, it is not protecting anything. Use a few end-to-end tests for critical journeys and let faster, focused tests cover the rest.

    testing-library.comTestingBeginner

Security 4

  • OWASP Top 10: The Standard Awareness List for Web Risks

    The widely referenced list of the most critical web application security risks, with explanations and prevention advice for each. Use it as a shared vocabulary for reviews and threat conversations, and as a map of what to study next.

    owasp.orgSecurityBeginner
  • Hacksplaining: Interactive Lessons on How Attacks Work

    Short, free, interactive lessons that walk through attacks such as SQL injection and cross-site scripting, then show how to prevent them in code. A friendly way to see the attacker view before you dig into deeper labs.

    hacksplaining.comSecurityBeginner
  • Broken Access Control: Stop Users Reading Each Other's Data

    In the 2021 edition of the OWASP Top 10 this category ranked first, and the common form is simple: change an id in a URL and see someone else's record. Here $2 comes from the authenticated session, never from the request. Habits that prevent most cases: - Deny by default; require an explicit permission check on every endpoint. - Enforce authorization on the server for every request. Hiding a button is not access control. - Centralize checks in one policy layer instead of scattering ad hoc ifs. - Prefer unguessable ids as defense in depth, not as the only defense. - Write tests that log in as user A and request user B's resources, expecting 403 or 404. Log denied attempts and alert on bursts of them.

    owasp.orgSecurityBeginner
  • Challenge: Break and Fix a Query With SQL Injection

    Run this on your own machine, in a throwaway file, to see the attack and the fix side by side. About ten minutes with Python. The first query lets input rewrite the SQL. In the second, the driver sends the value separately from the statement, so it can only ever be data. Your tasks: 1. Predict the output before running. 2. Find one place in a project of yours that builds SQL by concatenation and convert it. 3. Handle what placeholders cannot: table names, column names and ORDER BY direction. Check those against a fixed allowlist in code. ORMs help but still allow raw string fragments, so review those too.

    owasp.orgSecurityBeginner

Cloud 4

  • AWS Well-Architected Framework: A Review Lens for Cloud Designs

    A set of questions and best practices across areas like security, reliability, cost and operations. Even outside AWS it is a handy checklist for design reviews, and the questions are free to read without an account.

    aws.amazon.comCloudIntermediate
  • Microsoft Learn: Free Cloud Fundamentals and Role-Based Paths

    Free, structured modules and learning paths on cloud concepts, networking, identity and DevOps, many with sandbox environments. A solid starting point if you want guided practice instead of piecing docs together alone.

    learn.microsoft.comCloudBeginner
  • IAM Least Privilege: Grant What the Job Needs, Nothing More

    Broad permissions turn a small leak into a big incident. The AWS IAM best-practices guide is worth reading even if you use another cloud, because the ideas transfer. Core habits: prefer temporary credentials (roles) over long-lived access keys, require MFA for people, remove unused identities, and start narrow. A scoped policy, read access to one prefix in one bucket: How to get there in practice: begin with the smallest policy you can, test, and add what is denied. IAM Access Analyzer can help by generating a policy from recorded activity and by flagging resources shared outside your account. Remember that an explicit deny always wins over an allow, and avoid wildcards in both actions and resources unless you can justify them. Review roles on a schedule; permissions only ever grow unless someone prunes them.

    docs.aws.amazon.comCloudIntermediate
  • Challenge: Audit Your Cloud Account for Public Storage

    Accidentally public buckets are a classic cloud leak. Spend fifteen minutes checking an AWS account you own, using read-only commands. (Other clouds have equivalents; the habit is the point.) How to read the results: - get-public-access-block shows whether the four Block Public Access settings are on. An error saying no configuration exists means that bucket has none. - get-bucket-policy-status reports IsPublic for the bucket policy. - Also check the account-level setting with aws s3control get-public-access-block --account-id <id>. Your tasks: list every bucket that is not fully blocked, write down why each should be public (usually none should), and plan to enable Block Public Access at the account level. Serve public websites through a CDN instead of opening buckets. Do not change anything until you know which application depends on it.

    docs.aws.amazon.comCloudBeginner

Debugging 3

  • Brendan Gregg on Linux Performance: Tools Mapped to the Stack

    A reference page that maps observability and tracing tools to the parts of a Linux system they inspect, with diagrams and talks. Reach for it when a box is slow and you need to know which tool answers which question.

    brendangregg.comDebuggingAdvanced
  • The USE Method: A Checklist for Finding Bottlenecks

    A simple method for performance problems: for every resource, check utilization, saturation and errors. It gives you a systematic order of questions instead of guessing, and applies to CPUs, disks, networks and queues alike.

    brendangregg.comDebuggingAdvanced
  • Debug Production With Logs, Metrics and Traces: Start With a Question

    Production debugging goes faster when you pick the right signal. Roughly: metrics say that something is wrong, traces say where in the request path, and logs say why. A workable sequence: 1. State the symptom as a measurable question: "p95 latency of checkout rose after 14:00". 2. Use metrics to scope it: which service, endpoint, region, version? 3. Open a slow trace to find the span that takes the time. 4. Search logs for that request id to read the detail. This only works if you prepared. Emit structured logs (JSON with fields) and include a request or trace id in every line, and pass it across service calls. Keep metric labels low-cardinality, so avoid user ids as labels. Then form one hypothesis at a time and test it with a query, instead of changing things. The OpenTelemetry primer linked here explains the vocabulary of signals, context propagation and instrumentation clearly.

    opentelemetry.ioDebuggingIntermediate

Career 3

  • Tech Interview Handbook: Resume, Coding and Behavioral Prep

    A free, curated handbook on the whole job search: resumes, preparing for coding rounds, behavioral questions and negotiation. Use it as a single organized starting point, then dive into the sections that match your stage.

    techinterviewhandbook.orgCareerBeginner
  • StaffEng Guides: Growing Beyond Senior Engineer

    Practical guides on technical leadership at senior levels: scope, influence, working with leadership and writing for decisions. Helpful even earlier, since it shows which habits you can start building now.

    staffeng.comCareerAdvanced
  • Resume Basics: One Page That Survives a Quick Skim

    A recruiter or engineer may spend under a minute on a first pass, so optimize for scanning. Structure: contact line, short experience entries in reverse chronological order, projects, education, skills. Keep it to one page when you have under roughly a decade of experience. Write each bullet as action, what you did, and the result: Only use numbers you can defend in an interview; if you cannot measure it, describe the visible outcome honestly. Lead with the technologies that matter for the role, drop the ones you would not want to be quizzed on, and skip photos, rating bars and long objective statements. Practical checks: export to PDF, make the text selectable, use a standard font, and ask a friend to circle the first three things they remember. Tailor the top third for each application.

    techinterviewhandbook.orgCareerBeginner

Soft Skills 3

  • Google Technical Writing Courses: Clearer Docs, Issues and Emails

    Free, short courses on writing clear technical prose: precise words, active voice, organizing documents and reviewing drafts. Useful for design docs, pull request descriptions and any message that others must act on.

    developers.google.comSoft SkillsBeginner
  • Code Review That Helps: Habits for Authors and Reviewers

    Google's public engineering practices describe a simple standard: approve a change once it improves the overall health of the codebase, even if it is not how you would have written it. Perfect is not the bar. For authors: - Keep changes small and focused; they get reviewed faster and more carefully. - Write a description that says what and why, and link the issue. - Review your own diff first and run the tests. For reviewers: - Look at design, correctness, tests, naming and readability, roughly in that order of importance. - Prefix minor preferences with "Nit:" so the author knows they are optional. - Explain why, and ask questions before assuming a mistake. - Respond promptly. Waiting for review is the biggest cost to the author. Disagreement tip: when stuck in a loop, move to a call or a short design chat, then write the outcome in the thread. Comment on the code, never on the person.

    google.github.ioSoft SkillsIntermediate
  • Write a Design Doc That Surfaces Trade-offs Early

    A design doc is for finding problems while changes are still cheap. It is worth writing when a design is ambiguous or the choice involves real trade-offs, and not worth it when it would only describe obvious implementation. A useful outline: 1. Context and scope: what this is and why now. 2. Goals and non-goals: non-goals prevent argument about things you never meant to solve. 3. The design: overview first, then APIs, data storage and key flows, with a diagram. 4. Alternatives considered, and why each lost. 5. Cross-cutting concerns: security, privacy, observability, rollout. Keep it short for small work; a page or two is fine. Large projects naturally run longer, but split anything that sprawls. Before sending, ask: could a reader tell what decision I want from them? Put that at the top, name reviewers, and set a date for comments. Record the final decision in the doc so it remains useful later.

    industrialempathy.comSoft SkillsIntermediate

Interviews 2

  • NeetCode Roadmap: A Structured Path Through Coding Problems

    A free roadmap that groups algorithm problems by pattern, such as two pointers, graphs and dynamic programming, with a visual map of dependencies. Handy for turning random practice into a deliberate plan for coding interviews.

    neetcode.ioInterviewsIntermediate
  • Behavioral Interviews: Build a Story Bank Before You Need It

    Behavioral questions test judgment and teamwork. Prepare, because improvised stories ramble. A reliable shape is STAR: Situation, Task, Action, Result. Spend most of your time on Action and Result, and say "I" for what you did and "we" for what the team did. Build a bank of four or five real stories from your work, studies or projects, and tag each with themes: - a conflict or disagreement you worked through - a failure and what changed afterward - a tight deadline or trade-off - leading or helping without authority - something you learned quickly Write each as bullet points, not a script, then practice aloud and time it to about two minutes. Prepare the follow-ups too: what would you do differently, and what did you measure? Use only experiences that really happened. Interviewers probe details and inconsistencies show quickly. Finish with a result and a lesson, and close the loop if asked.

    techinterviewhandbook.orgInterviewsBeginner

More from the Vault

Talk it through with people who use these

Ask about any of these in the server, share what you build with them, and get new picks every day.

Join on Discord