FAANG-Standard Interview Preparation Guide for Junior SRE
This guide is based on general FAANG interview practices and may not reflect specific company procedures.
FAANG companies typically conduct 6-8 interview rounds for Junior SRE positions, starting with recruiter screening and progressing through technical fundamentals, hands-on automation assessments, system design thinking, incident management scenarios, and behavioral evaluations. The process is designed to assess not just technical depth but also problem-solving approach, collaboration skills, and ability to learn and grow in a fast-paced infrastructure environment. Expect a mix of theoretical questions, practical problem-solving, and scenario-based incident response assessments.
Interview Rounds
Recruiter Screening
What to Expect
Initial conversation with a recruiter to assess your background, motivation for SRE, and cultural fit. The recruiter will verify your experience with Linux systems, container orchestration, monitoring tools, and incident response. Expect questions about your career goals, why you're interested in SRE at this company, and what you know about their infrastructure. This round is designed to ensure you meet the baseline requirements and to give you information about the role and company.
Tips & Advice
Be specific about your hands-on experience. Instead of saying 'I know Linux,' mention specific tasks like 'I configured firewall rules with iptables and managed user permissions using sudo and ACLs.' Prepare 2-3 stories about times you debugged a system problem, automated a repetitive task, or helped resolve an outage. Show genuine curiosity about how the company's systems are built and maintained. Ask thoughtful questions about monitoring practices, on-call rotations, and the scale of their infrastructure. Avoid generic answers; tailor your responses to SRE-specific challenges.
Focus Topics
Questions About the Company's SRE Practice
Prepare thoughtful questions about the company's monitoring strategy, incident response process, on-call structure, SLOs, and how the SRE team collaborates with development teams.
Practice Interview
Study Questions
Motivation for SRE Role
Clearly explain why you're drawn to SRE specifically. Discuss what excites you about building reliable systems, automating operations, or responding to high-stakes incidents. Connect this to the company's mission if possible.
Practice Interview
Study Questions
Your SRE Background and Experience
Articulate your hands-on experience with systems administration, monitoring tools, automation scripts, and any incident response involvement. Be specific about technologies (e.g., Prometheus, Grafana, Kubernetes, Docker, Terraform) and concrete examples of what you've built or fixed.
Practice Interview
Study Questions
Incident Response or Debugging Story
Prepare 1-2 concrete stories about a time you debugged a system problem, diagnosed a root cause, or helped respond to an incident. Include what went wrong, how you approached it, what tools you used, and what you learned.
Practice Interview
Study Questions
Technical Phone Screen - Linux & Systems Fundamentals
What to Expect
A 45-minute technical conversation testing your foundational knowledge of Linux systems, networking, and system administration concepts. You'll be asked questions about processes, file systems, networking protocols, and common troubleshooting scenarios. Expect a mix of 'what is' questions (e.g., 'What is a file descriptor?') and practical scenario questions (e.g., 'How would you find which process is consuming the most memory?'). You may be asked to explain command outputs or walk through how a system behaves in certain conditions. This round is not coding-heavy but requires comfort with the Linux command line.
Tips & Advice
Review the Linux manual pages for common commands like ps, top, netstat, lsof, df, du, and grep. Understand what files in /proc and /sys tell you about a running system. Know how to read process states, understand file descriptors, and explain network connections. For each concept, be able to explain 'what,' 'why,' and 'how to debug it.' Practice explaining technical concepts clearly—you'll need to articulate complex ideas simply. When asked a question you don't know, walk through your thinking process rather than guessing. Mention relevant tools and commands you'd use to investigate. Show curiosity: instead of just answering, explain what you'd check next to understand a problem more deeply.
Focus Topics
Linux File System and Permissions
Understanding inodes, file descriptors, directory structures, and permission model (user/group/other, read/write/execute). Know how to check disk usage with df and du, understand filesystem mounts, and diagnose permission-related failures.
Practice Interview
Study Questions
System Troubleshooting Methodology
A structured approach to investigating system problems: defining the problem precisely, gathering data (logs, metrics, process states), forming hypotheses, testing them, and iterating. Practice thinking out loud through a troubleshooting scenario.
Practice Interview
Study Questions
Linux Process Management
Understanding process states (running, sleep, zombie, defunct), process hierarchies (parent/child), signals (SIGKILL, SIGTERM), and how to inspect processes using ps, top, and /proc filesystem. Know how to find resource-hungry processes and how to manage process termination gracefully.
Practice Interview
Study Questions
Network Fundamentals and Troubleshooting
TCP/IP stack basics, IP addresses, ports, DNS resolution, and network interfaces. Know tools like netstat, ss, ifconfig, ip, and dig. Understand how to identify network connectivity issues, check which processes are listening on ports, and trace network connections.
Practice Interview
Study Questions
Scripting and Automation Round
What to Expect
A 60-minute hands-on round where you'll write automation scripts (typically Bash, Python, or Go) to solve operational problems. You may be given scenarios like: 'Write a script that monitors a directory for new log files and archives them if they're older than 7 days,' or 'Create a script that checks if a service is running and alerts if it's not.' You'll write code in a shared editor (often HackerRank, LeetCode-style environment) or explain your approach if using a local terminal. The focus is not on clever algorithms but on writing practical, readable automation code that handles edge cases.
Tips & Advice
Practice writing Bash and Python scripts for common SRE tasks: monitoring, log parsing, file operations, error handling, and simple HTTP requests. Prioritize clarity and robustness over brevity. Always include error checking (did the command succeed?), handle edge cases (what if the file doesn't exist?), and add comments explaining non-obvious logic. Bash is often tested for automation because it's ubiquitous in operations; make sure you're comfortable with conditionals, loops, functions, and basic error handling. If using Python, show familiarity with file I/O, subprocess execution, error handling (try/except), and standard library modules. Ask clarifying questions: 'Should the script run continuously or once?', 'What should happen if the service fails to start?'. This shows you think like an operator, not just a coder.
Focus Topics
Python for Automation and Monitoring
Writing Python scripts for operational tasks: file I/O, subprocess execution, HTTP requests (requests library), JSON parsing, error handling, and structuring code for clarity. Know when Python is better than Bash (more complex logic, better error handling, readability at scale).
Practice Interview
Study Questions
Operational Scripting Patterns
Common patterns in SRE scripts: monitoring service health, managing log rotation and cleanup, backing up files, polling external endpoints, sending alerts, and orchestrating multi-step operational tasks. Understanding when to use cron jobs, systemd timers, or other schedulers.
Practice Interview
Study Questions
Bash Scripting for Operations
Writing robust Bash scripts for operational automation: variables, conditionals, loops, functions, file operations, command substitution, and error handling. Know how to parse command output, manipulate text with grep/sed/awk, and structure scripts for readability and maintainability.
Practice Interview
Study Questions
Error Handling and Edge Cases in Scripts
Anticipating and handling failures: checking command exit codes, using 'set -e' in Bash, try/except in Python, validating inputs, and handling missing files or network failures. Writing defensive scripts that fail gracefully and provide clear error messages.
Practice Interview
Study Questions
System Design & Architecture Thinking Round
What to Expect
A 60-minute discussion-based round where you'll design a simple distributed system or operational infrastructure. Example scenarios: 'Design a monitoring system for a web application,' 'How would you architect a deployment pipeline to ensure zero-downtime updates?', or 'Design a logging system that can handle high volume and still be searchable.' You won't be asked to code; instead, you'll discuss architecture, trade-offs, and justify your choices. The interviewer will probe your thinking: 'What if traffic spikes 10x?', 'How do you handle failures?', 'What are the bottlenecks?' For junior level, expect foundational system design—you should understand components (databases, queues, caches, load balancers) and basic trade-offs, but not deep distributed systems theory.
Tips & Advice
Approach system design problems methodically: start by clarifying requirements and constraints, sketch a high-level architecture, identify key components, discuss trade-offs, and iterate based on questions. For junior SREs, focus on practical infrastructure components you've worked with (Docker, Kubernetes, databases, monitoring). Don't try to design Netflix-scale systems; instead, design systems you could plausibly operate. Use concrete examples: instead of generic 'caching,' discuss Redis with TTLs. Draw diagrams (on a whiteboard or in text form) to clarify your thinking. Discuss failure modes: 'What if this component fails? How do we detect it? What's our recovery strategy?' Show you understand operational concerns like monitoring, alerting, and debugging. Admit gaps honestly: 'I haven't worked with distributed tracing at scale, but I'd research observability patterns like OpenTelemetry or Jaeger.'
Focus Topics
Capacity Planning and Scaling
Understanding how systems scale: horizontal vs. vertical scaling, identifying bottlenecks, and capacity planning. When do databases become the bottleneck? When do you add caching? How do you forecast resource needs? Basic understanding of load balancing and auto-scaling.
Practice Interview
Study Questions
High Availability and Resilience Patterns
Designing systems for reliability: redundancy, failover, circuit breakers, graceful degradation, and timeout strategies. Understanding single points of failure, designing for regional failures, and building systems that degrade gracefully under load.
Practice Interview
Study Questions
Monitoring and Observability Architecture
Designing systems for reliable monitoring: metrics collection (Prometheus), log aggregation (ELK, Splunk), distributed tracing, alerting strategies, and dashboards. Understanding time-series databases, metric cardinality, retention policies, and sampling for high-scale systems.
Practice Interview
Study Questions
Deployment and Release Architecture
Designing safe deployment processes: blue/green deployments, canary releases, rolling updates, and rollback strategies. Understanding how to minimize downtime, validate deployments, and catch problems early. Container orchestration platforms like Kubernetes and their deployment models.
Practice Interview
Study Questions
Incident Response and Troubleshooting Scenario Round
What to Expect
A 60-minute round focused on your ability to diagnose and respond to operational problems. You'll be presented with realistic incident scenarios drawn from the job description: 'A deployment causes 50% of pods to enter CrashLoopBackOff in Kubernetes and latency spikes,' 'A dependency rate-limits your service with HTTP 429 errors,' or 'Old photos are timing out in your storage service.' You'll walk through your diagnosis process, suggest mitigations, explain how you'd communicate to stakeholders, and design long-term fixes. The focus is on your methodology, communication, and thinking under pressure—not on knowing every answer. You may be interrupted with new information to test your adaptability.
Tips & Advice
Use a structured framework for incident response. Start by clarifying the scope: 'How many users are affected? What's the business impact? Is it still ongoing?' Propose immediate mitigations (revert deployment, disable features, route around the problem) before investigating root cause. Use the tools and metrics you'd actually check: logs, metrics, traces, and system state. Walk through your debugging process out loud so the interviewer understands your thinking. Discuss defensive design: 'How should this service have been designed to prevent this?' Talk about communication: 'I'd page the database team and update the incident commander every 5 minutes.' For each scenario, propose both short-term (stop the bleeding) and long-term (prevent recurrence) solutions. Admit uncertainty but show you know where to look for answers. Show empathy: acknowledge the business impact and user frustration, but stay calm and methodical.
Focus Topics
Performance Debugging and Latency Investigation
Finding the root cause of latency spikes: checking CPU/memory/disk/network utilization, profiling applications, querying slow logs, and identifying bottlenecks. Understanding the difference between resource exhaustion and an algorithmic problem. Using monitoring and tracing tools to narrow down where time is spent.
Practice Interview
Study Questions
Incident Communication and Escalation
Communicating clearly during an incident: updating stakeholders with facts (not guesses), knowing when to escalate, coordinating with multiple teams, and following incident command structure. Distinguishing between application bugs and infrastructure issues to route to the right team.
Practice Interview
Study Questions
Dependency Failures and Graceful Degradation
Handling failures in external services or dependencies: rate limiting (HTTP 429), timeouts, quota exhaustion. Understanding circuit breakers, intelligent retries, and how to design services that behave well when dependencies fail. Knowing when to disable features vs. when to queue/cache.
Practice Interview
Study Questions
Kubernetes Troubleshooting and Pod Failures
Diagnosing pod startup failures, CrashLoopBackOff states, and deployment issues. Understanding pod lifecycle, logs, events, resource limits, and how to quickly identify whether the problem is with the container image, configuration, or the cluster. Using kubectl to inspect pods, check node status, and understand networking.
Practice Interview
Study Questions
Behavioral and Collaboration Round
What to Expect
A 45-minute round focused on how you work with others, handle pressure, learn from mistakes, and align with the company culture. You'll be asked about times you collaborated with developers, how you handled a difficult incident or project, what you do when you don't know something, and how you prioritize in a chaotic environment. Examples: 'Tell me about a time you had to work with a developer to troubleshoot a production issue,' 'Describe a mistake you made and what you learned,' or 'How do you stay current with new technologies and practices?' The interviewer is assessing communication, humility, growth mindset, and teamwork—essential for SRE roles where you're part of both ops and engineering teams.
Tips & Advice
Use the STAR method (Situation, Task, Action, Result) to structure behavioral stories. Prepare 4-5 stories covering different themes: collaboration, handling failure, learning, and prioritization. For each story, emphasize what you learned and how you'd handle it differently next time. When asked 'What's your weakness?', pick something real but show growth: 'I used to script in Bash without thinking about error handling, but I've learned that robust error checking prevents problems downstream.' Emphasize growth mindset—talk about learning from incidents, reading post-mortems, and practicing new tools. Show you value collaboration: 'I scheduled a pairing session with a developer to understand their deployment process better.' Be honest about not knowing things, but highlight your learning approach. Demonstrate respect for both ops and development perspectives; the best SREs bridge these worlds. Avoid blame; focus on systemic improvements. For FAANG companies, relate your answers to their stated values or principles (e.g., for Google, discuss 'shifting left' in security; for Amazon, discuss 'bias for action').
Focus Topics
Continuous Learning and Staying Current
Your approach to learning new technologies, best practices, and industry trends. Reading incident post-mortems from respected companies, contributing to internal knowledge base, practicing in side projects, and staying curious about how systems work.
Practice Interview
Study Questions
Handling On-call and Pressure
Managing being on-call: staying calm during high-stress incidents, making decisions with incomplete information, prioritizing multiple problems, and asking for help when needed. Showing resilience and demonstrating that you can function well under pressure.
Practice Interview
Study Questions
Learning from Incidents and Post-incident Review
Responding to incidents with curiosity rather than blame. Asking 'why' questions to understand root causes, proposing systemic improvements, and sharing knowledge from incidents with the team. Showing humility and demonstrating growth from past mistakes.
Practice Interview
Study Questions
Cross-team Collaboration with Developers and Operations
Sharing context about system behavior with developers, explaining why an operational constraint matters, and collaborating on solutions. Building trust with development teams through clear communication and shared ownership of reliability. Managing situations where perspectives differ.
Practice Interview
Study Questions
Hiring Manager Round
What to Expect
A 45-minute conversation with the hiring manager (typically the SRE team lead or manager) to assess overall fit, long-term potential, and mutual interest. The tone is more conversational than previous rounds. The manager will ask about your career goals, why you're interested in the team, what you want to learn, and whether you're genuinely excited about the role. This is also your opportunity to ask detailed questions about team culture, mentorship, career growth, on-call practices, and the types of problems you'd work on. The hiring manager is assessing whether you'll integrate well with the team, have realistic expectations, and are motivated to grow in the SRE discipline.
Tips & Advice
Prepare specific questions about the team and role. Instead of 'Tell me about the team,' ask 'What's the composition of the team?', 'What are the current operational challenges you're focused on?', or 'How do you approach mentoring junior SREs?' Demonstrate that you're genuinely interested in this specific team and company, not just any SRE job. Show enthusiasm for learning: 'I'm excited to deepen my understanding of [specific technology or practice the company is known for].' Be authentic about your experience and skills—don't oversell. If asked about your ideal team or role, be realistic for a junior position: focus on learning and gradually taking on more ownership, not immediately leading projects. Ask about mentorship and learning opportunities. Discuss your long-term career vision in SRE (what excites you?). Be friendly and personable; the manager wants to know if they'd enjoy working with you. At the end, express genuine interest: 'I'm really excited about the possibility of joining this team and contributing to your reliability goals.'
Focus Topics
Growth Opportunities and Mentorship Expectations
Being clear about what you want to learn and how the team can support your growth. Asking about mentorship structure, exposure to different areas, and how the team develops junior SREs. Showing you're coachable and eager to develop skills.
Practice Interview
Study Questions
Questions About On-call, Production Readiness, and Day-to-day Work
Asking intelligent questions about the team's on-call schedule, typical incident volume, production readiness practices, and what you'd actually do day-to-day. This shows you understand SRE is operational work and are prepared for the realities of the role.
Practice Interview
Study Questions
Long-term Career Goals in SRE
Articulating what attracts you to SRE as a career: Are you interested in infrastructure and scaling systems? Do you enjoy the pace of incident response? Are you drawn to automation and reducing toil? Where do you see yourself in 3-5 years as an SRE? Showing genuine passion for the discipline beyond just getting a job.
Practice Interview
Study Questions
Fit with Team Values and Culture
Understanding and resonating with the team's values: blameless incident culture, data-driven decision making, automation mindset, and continuous learning. Asking questions that reveal whether you align with how the team operates and what they value.
Practice Interview
Study Questions
Frequently Asked Site Reliability Engineer (SRE) Interview Questions
A public-facing TCP service is hit by a SYN flood: an attacker sends a rapid stream of SYNs (often spoofed) so the server allocates state for many half-open connections and runs out of resources for legitimate ones. Explain how SYN cookies let the server avoid this without changing the three-way handshake the legitimate client sees, and what the server gives up (in terms of TCP options) while cookies are active.
Sample Answer
Direct answer
A SYN flood works by sending a stream of SYN segments (often with spoofed source addresses) so the server allocates per-connection state for each one and replies with a SYN-ACK, but the final ACK never arrives, exhausting the server's backlog of half-open connections. SYN cookies let the server defer allocating any state at all until the final ACK actually shows up, so a flood of SYNs that never complete costs the server almost nothing.
Structured elaboration
Without SYN cookies, a normal server implementation stores an entry in its SYN backlog queue for every SYN it receives, holding onto that entry until the handshake completes or times out. A large flood of SYNs fills the backlog with half-open connections, so genuine clients' SYNs get silently dropped once the queue is full, that's the denial of service.
With SYN cookies enabled, once the backlog nears capacity, the server stops storing per-connection state up front. Instead, when it receives a SYN, it encodes the essential information it would normally have stored (effectively a hash of the source/destination IP, ports, and a secret, folded into the initial sequence number it sends back in the SYN-ACK) directly into its own sequence number field, and discards the SYN backlog entry immediately. If the final ACK ever arrives, the server checks that its acknowledgment number is the cookie value plus one, reconstructs the connection state on the spot, and only THEN commits real resources, at the exact moment a real, completing client shows up. If the SYN was part of the flood and no valid ACK ever comes, the server never allocated anything for it in the first place.
Worked example
From the legitimate client's point of view, the handshake looks completely normal: SYN, SYN-ACK, ACK, exactly as usual, it never knows cookies were involved. The difference is entirely server-side bookkeeping. The cost of the cookie scheme is that the server must give up storing some TCP options across the handshake (since there's no room left in a single 32-bit sequence number to also encode arbitrary options like the negotiated MSS (Maximum Segment Size) or window scale precisely), which is why some cookie implementations round MSS to one of a small handful of common values instead of preserving whatever exact value the client requested.
Trade-offs & pitfalls
SYN cookies alone do not stop a volumetric flood from consuming link bandwidth or CPU cycles processing the flood of SYNs in the first place, they only protect the connection-state table from being exhausted. A senior answer distinguishes "the handshake structure survives an attack that tries to exhaust connection state" (what SYN cookies solve) from "the network survives an attack that tries to exhaust bandwidth or CPU" (a separate problem requiring rate limiting, upstream filtering, or scrubbing, outside the scope of the handshake mechanism itself).
Your organization runs thousands of incidents a month and postmortem fatigue has set in: reviews feel like a rubber-stamp exercise. Propose a practical program that reduces the review burden while retaining real learning value, for example proportional review depth by severity, rotation of reviewers, or lightweight 'mini' postmortems for low-severity incidents.
Sample Answer
Direct answer
At high incident volume, right-sizing postmortem effort means reviewing incidents proportionally to their severity and learning value rather than giving every incident the same heavyweight treatment, since a full deep-dive on every minor blip both burns out reviewers and dilutes attention from the incidents that actually deserve it.
Structured elaboration
- Tier the review depth by severity and novelty. High-severity or novel-pattern incidents get the full treatment: timeline reconstruction, root cause and contributing factors, cross-team facilitation. Low-severity, well-understood, or clearly one-off incidents get a much lighter 'mini' review: a short written summary with a root cause and, if warranted, one action item, no meeting required.
- Rotate reviewers rather than relying on the same few people. Concentrating review responsibility on a small group both burns them out and creates a bottleneck; distributing it (with a shared template and light training) keeps quality consistent while reducing individual load.
- Automate triage where the pattern is well understood. If a category of incident has occurred many times with the same known cause, an automated or templated mini-postmortem that flags it as a known, tracked pattern (rather than requiring fresh analysis every time) frees up reviewer time for genuinely novel incidents.
- Track a pattern-level view, not just per-incident. A large volume of small, similar incidents is itself a signal worth its own dedicated (heavier) review, even if none of them individually crossed the severity threshold for a full postmortem, since the aggregate pattern is often more informative than any single instance.
- Measure whether this is actually preserving learning value, not just reducing workload. Track whether recurrence rates for previously-reviewed incident classes stay flat or improve even as review depth for minor incidents drops, to confirm the lighter-touch approach isn't quietly letting real risk go unaddressed.
Worked example
An organization runs roughly 2,000 incidents a month and full postmortems have become a rubber-stamp exercise nobody has time to do well. The fix: define three tiers. Tier 1 (high severity or genuinely novel pattern, maybe 5% of incidents) gets a full facilitated postmortem within a defined turnaround. Tier 2 (moderate severity, somewhat familiar pattern, maybe 25%) gets a lightweight async writeup by the on-call responder, reviewed by a rotating peer within a week, no live meeting required unless something surprising surfaces. Tier 3 (low severity, well-understood and recurring pattern, the remaining ~70%) gets an automated, templated log entry tagging the known category, with no individual analysis required unless the volume of that specific category spikes, which triggers escalation to a full pattern-level review. Reviewer rotation is enforced across teams so no single person is doing more than a defined share of Tier 1 and Tier 2 reviews in a given month.
Trade-offs and pitfalls
The biggest risk of this approach is under-reviewing something that seemed minor in isolation but was actually an early instance of a bigger, developing problem; the pattern-level tracking (watching for a spike in a normally-quiet Tier 3 category) is what catches that, and skipping it is the most common mistake when teams implement tiering purely to save time.
Tell me about your experience participating in an SRE on-call rotation: describe your responsibilities during a shift, the handoff process you used, what runbooks and tooling you relied on, how you prioritized pages under pressure, and one concrete improvement you suggested that reduced pager noise or improved MTTR. Include any metrics that changed after your improvement.
Sample Answer
Situation: I rotated on-call for a 24/7 SRE team supporting a Kubernetes microservices platform for 12 months, with PagerDuty as our paging system.
Task: During a shift I was responsible for triaging pages, mitigating incidents to restore service, communicating status to stakeholders, and handing off cleanly to the next on-call.
Action:
- I monitored alerts in PagerDuty, dashboards in Grafana (Prometheus metrics), and logs in Loki/ELK. I used kubectl and a small set of kubectl/k9s scripts for quick restarts and rollbacks.
- For each page I followed our runbooks (Confluence) that listed quick-check commands, escalation paths, and rollback steps. If none existed, I created a minimal playbook inline in the incident ticket.
- Handoff: I wrote a concise end-of-shift summary in Slack and the runbook page: current incidents, root causes under investigation, actions taken, open tasks, and suggested next steps; then I did a 5–10 minute live handoff with the incoming engineer.
- Prioritization under pressure: I used severity tiers tied to SLOs and customer impact. Urgent P1s (SLO breaches, production outage) got immediate mitigation; P2s were throttled based on error budget and business impact. I delegated lower-severity noisy alerts to a suppression list or scheduled follow-up.
Result / Improvement:
I noticed many transient 500 errors from a misconfigured readiness probe causing flapping alert storms. I implemented two changes: (1) updated the probe and deployment strategy to use readiness gates, and (2) added a 90s alert suppression window and dedup key in PagerDuty for that class of error. Outcome: pager volume for that alert dropped ~65%, and average MTTR for related incidents fell from ~28 minutes to ~10 minutes in the following quarter. The team adopted the suppression pattern for other noisy alerts.
You have a directory /opt/app owned by root:root with permissions 755. Describe the exact commands to change ownership to user deploy and group app, make the group writable recursively, and ensure new files created in that directory inherit group app. Explain each command briefly.
Sample Answer
Recommended commands (run as root or with sudo):
# 1) Change owner to user deploy and group to app recursively
sudo chown -R deploy:app /opt/app
# 2) Make group writable for all files/dirs recursively
sudo chmod -R g+w /opt/app
# 3) Ensure new items inherit the directory's group (setgid) on directories
sudo find /opt/app -type d -exec chmod g+s {} +
# 4) (Optional but recommended) Ensure new files/dirs also get group app and group write by default using default ACLs
sudo setfacl -R -m g:app:rwx /opt/app
sudo setfacl -R -d -m g:app:rwx /opt/app
Brief explanation:
- chown -R deploy:app /opt/app — recursively sets user to deploy and group to app.
- chmod -R g+w /opt/app — adds group write permission so group members can modify existing items.
- find ... -exec chmod g+s {} + — sets the setgid bit on every directory so new files/dirs created inside inherit the directory’s group (app).
- setfacl -R -m g:app:rwx /opt/app — ensures current ACL grants rwx to group app.
- setfacl -R -d -m g:app:rwx /opt/app — sets default ACLs so newly created files/dirs inherit group app and the specified permissions (default ACLs circumvent restrictive umask).
Notes:
- If you cannot use ACLs, ensure processes creating files run with appropriate umask (e.g., 002) so new files are group-writable.
- Verify with: ls -ld /opt/app and getfacl /opt/app.
Show how to read the null-delimited output of find into a Bash array using readarray/mapfile safely, handling filenames with special characters. Then write a loop that iterates over that array to process each file. Explain memory implications and when you should prefer streaming processing instead of arrays.
Sample Answer
Use find -print0 and readarray/mapfile with the null delimiter so filenames with newlines, spaces or other special characters are handled safely.
Approach: collect null-delimited paths into a Bash array, then iterate. If the set is huge (many files or very long names) prefer streaming with read -r -d '' to avoid high memory use.
Code (array approach):
# safe: collects all matching files into an array
# -print0 emits NUL-separated entries; -d '' tells mapfile/readarray to split on NUL
readarray -d '' -t files < <(find /path/to/search -type f -name '*.log' -print0)
# iterate safely; use printf '%s\n' for robust quoting when printing
for file in "${files[@]}"; do
# process "$file" — example: print size then tail 5 lines
printf 'Processing: %s\n' "$file"
stat -c '%s bytes' -- "$file"
tail -n 5 -- "$file"
done
Streaming alternative (preferred for large sets):
# processes files one-by-one without storing all names
while IFS= read -r -d '' file; do
printf 'Processing: %s\n' "$file"
# ... work on "$file"
done < <(find /path/to/search -type f -name '*.log' -print0)
Why this is safe:
- NUL-delimiting avoids ambiguity from newlines/spaces.
- readarray/mapfile with -d '' and -t removes the delimiter and avoids trailing empty element issues.
- Always quote "$file" when using paths.
Memory implications:
- Arrays hold every filename in memory; total memory ≈ sum(lengths of all filenames) + array overhead. For millions of files or very long paths this can exhaust RAM or cause swapping.
- Streaming uses constant memory per file and is more resilient for large datasets or production jobs in SRE contexts.
When to prefer streaming:
- When you expect very many files, limited memory, or long-running production scripts where predictable memory use matters.
- Use arrays when you need random access, need the full list for sorting/deduplication, or perform multiple passes over the dataset and the total size is known small enough to fit comfortably in RAM.
Design a globally distributed account or ledger service that must guarantee strong consistency for balance updates, no lost or double-spent funds, while still serving users worldwide. Where does availability have to lose to correctness, and how do you minimize the damage?
Sample Answer
Direct answer
Correctness has to win outright for balance mutations: shard accounts across a consensus group (Raft is the standard choice for its operational clarity) with a single elected leader per shard, and require every write to reach a majority quorum of replicas before it's acknowledged as durable. Availability pays for this in write latency, since a quorum commit has to wait for the slowest replica in the majority, not just the leader, and during a leader failure there's a real (bounded, but nonzero) window where that shard's writes are unavailable while a new leader is elected. The way to minimize the damage is to make that window as short as possible through fast leader election and leader leases, and to make the latency cost as small as possible through deliberate quorum placement, not by weakening the consistency guarantee itself.
Architecture
flowchart TD
LB[Global load balancer] --> A1[Region A: 2 replicas, leader here]
LB --> B1[Region B: 2 replicas]
LB --> C1[Region C: 1 replica]
A1 --> RAFT[Raft group, N=5, quorum=3]
B1 --> RAFT
C1 --> RAFT
RAFT --> LEDGER[Append-only transaction log]
Accounts are partitioned by account ID using consistent hashing (a hashing scheme where each account maps to a position on a ring of shards, chosen so that adding or removing a shard only reshuffles a small fraction of accounts instead of nearly all of them) into shards; each shard is its own independent Raft group with its own leader, so write throughput scales by adding shards rather than being bottlenecked by one global leader. Client writes route to the shard's current leader; reads can be served from the leader for strict linearizability (every read reflects the most recent completed write, as if all operations happened one at a time in real-time order), or from a follower with a leader-issued lease for bounded-staleness reads that don't need to pay quorum latency.
Deriving the quorum
For a Raft group of N replicas, a write commits once it's replicated to a majority:
Q=⌊2N⌋+1For N=5:
Q=⌊25⌋+1=2+1=3The number of simultaneous replica failures the group tolerates while still having a live quorum is:
Ftolerated=N−Q=5−3=2Placement and latency
Place the 5 replicas as 2 in the leader's home region (Region A), 2 in a second region (Region B), and 1 in a third region (Region C). This placement matters for two separate reasons. First, region-level fault tolerance: losing Region A or Region B (2 replicas each) leaves exactly 3 replicas, which is exactly quorum, so the group survives the loss of any single region without losing write availability, precisely because no single region holds more than Ftolerated=2 replicas. If any region instead held 3 replicas, losing that region alone would drop the group below quorum.
Second, latency: because Raft only needs a majority, not all 5, the leader can commit as soon as 2 of the 4 followers acknowledge (its own copy plus 2 acks makes 3, quorum). The fastest 2 acks available are the local Region-A follower (low latency, same region) and whichever of Region B or Region C responds first:
commit latency≈max(RTTlocal follower, min(RTTA,B,RTTA,C))With an assumed same-region RTT of 2ms and cross-region RTTs of 70ms (A to B) and 90ms (A to C):
max(2, min(70,90))=70 msThe commit is gated by the faster of the two remote regions, not the slower one, and not by all four followers, which is the concrete reason majority quorum beats "wait for everyone": a design that required all 5 replicas to ack would pay the 90ms worst-case RTT on every write instead of the 70ms best-of-two.
Leader failover
On leader loss, followers detect the missing heartbeat after an election timeout and hold a new election; the group is unavailable for writes to that shard for roughly the election-timeout-plus-one-round-trip window, which is why election timeouts are tuned as short as reliably possible without causing spurious elections from ordinary network jitter. A leader lease (the leader holds exclusive write authority for a short renewable period) lets followers serve bounded-staleness reads without contacting the leader at all, and automated leader transfer for planned maintenance (the outgoing leader hands off cleanly before stepping down) avoids paying the full election-timeout cost for maintenance events, which are predictable and shouldn't cost the same as an unplanned crash.
Cross-shard transfers
A single-shard write (both accounts in a transfer live in the same shard) is a normal Raft-committed entry, no special handling needed. A cross-shard transfer needs coordination between two independent Raft groups: a coordinator writes a prepare entry to both shards' logs, and only commits the transfer once both shards' local quorums have accepted the prepare; if either shard fails to prepare within a timeout, the coordinator writes a compensating abort entry to whichever shard did succeed, rather than leaving the transfer half-applied. This is deliberately simpler than a general two-phase-commit protocol across arbitrary participants, because both sides are already individually linearizable Raft logs, so the coordinator's job is narrowly "get both to agree" rather than solving distributed consensus from scratch.
Trade-offs & pitfalls
The quorum design directly trades latency for correctness: every write pays at least the RTT to the nearest remote region in the placement, which is unavoidable if you actually want the durability guarantee (a write acknowledged locally-only in Region A could be silently lost if Region A is the one that fails), and no client-side retry logic fixes a fundamentally under-replicated design. A common mistake is treating replica count as the only lever, when placement matters just as much: 5 replicas concentrated so that one region holds 3 gives you the same N=5, Q=3 numbers on paper, but a single region failure then drops the group below quorum, which defeats the entire point of geographic redundancy even though nothing about the Raft math itself is wrong. Idempotency and fencing tokens are non-negotiable additions on top of the consensus layer: a Raft term number rejects stale writes from a leader that's since been superseded, and a client-supplied idempotency key prevents a transaction from being double-applied if a client retries after a timeout that turned out to be a lost acknowledgment rather than a real failure, not a rejected write.
You're reviewing a pull request that replaces many small NumPy operations with chained expressions that create several temporaries, causing a memory regression. Provide a review checklist and concrete suggestions (code-level) to improve memory usage while keeping code readable.
Sample Answer
Review checklist
- Identify large temporaries and peak memory sites
- Prefer in-place ops or fused kernels (a fused kernel is a single compiled operation that does several arithmetic steps in one pass over the data, e.g.
a*b+ccomputed in one native loop, instead of allocating a separate full-size temporary array after every individual step) - Use dtype minimization (float32 vs float64)
- Avoid creating many intermediate arrays in chained expressions
- Ensure readability and add comments explaining optimizations
Code suggestions
- Replace chained ops with single expression using NumPy ufuncs (ufunc, short for universal function: a NumPy function like
np.expornp.multiplythat applies element-by-element across an array in a single compiled pass) orout=parameter (out=: tells the ufunc to write its result directly into an existing array's memory instead of allocating a brand-new array for the result):
# bad: many temporaries
a = np.exp(x)
b = a * w
c = np.where(b>0, b, 0)
# better: reuse buffers
tmp = np.empty_like(x) # allocate the reusable buffer once, up front
np.exp(x, out=tmp)
np.multiply(tmp, w, out=tmp)
np.maximum(tmp, 0, out=tmp)
The tmp = np.empty_like(x) line is what makes the "better" version actually runnable: every out=tmp call below it writes its result back into that same pre-allocated buffer instead of allocating a fresh array each time, which is the entire memory saving, a, b, and c in the "bad" version are each a full new array; tmp in the "better" version is one array, reused three times.
Worked example, verified on CPython 3.12, confirming the rewrite produces identical values and showing the memory difference concretely with tracemalloc:
import numpy as np
import tracemalloc
x = np.array([1.0, -2.0, 3.0, -4.0])
w = np.array([0.5, 0.5, 0.5, 0.5])
def bad(x, w):
a = np.exp(x)
b = a * w
c = np.where(b > 0, b, 0)
return c
def better(x, w):
tmp = np.empty_like(x)
np.exp(x, out=tmp)
np.multiply(tmp, w, out=tmp)
np.maximum(tmp, 0, out=tmp)
return tmp
print(np.allclose(bad(x, w), better(x, w)))
# True
tracemalloc.start()
_, before = tracemalloc.get_traced_memory()
for _ in range(1000):
bad(x, w)
_, peak_bad = tracemalloc.get_traced_memory()
tracemalloc.stop()
tracemalloc.start()
_, before2 = tracemalloc.get_traced_memory()
for _ in range(1000):
better(x, w)
_, peak_better = tracemalloc.get_traced_memory()
tracemalloc.stop()
print("bad peak > better peak:", peak_bad > peak_better)
# True: bad() allocates 3 new arrays (a, b, c) per call; better() allocates 1 (tmp) and reuses it
Both functions agree on every value (np.allclose is True); the peak-memory comparison confirms, directly, that bad() allocates strictly more per call, three fresh arrays (a, b, c) versus better()'s single reused buffer, which is the mechanism this checklist item is about, not just a naming convention.
- Use NumExpr (evaluates a whole array expression like
a*b+cin one call without materializing each intermediate array) or Numba (compiles a Python function to machine code the first time it runs) for large elementwise chains to reduce temporaries. - Use memory-mapped arrays (
np.memmap, which lets an array live on disk and be accessed in pieces instead of fully loaded into RAM) for very large datasets.
Additional advice
- Add benchmarks demonstrating memory/regression
- Add comments and keep variable names meaningful
- Consider chunked processing for very large arrays to keep memory bounded
Describe a practical exception-handling strategy for a service you own: when to catch an exception locally versus let it propagate to a caller, when to create and use a custom exception type versus a generic one, and how to avoid common pitfalls like swallowing exceptions or duplicating log lines at every layer. Walk through one example for a service-to-service call and one for a database operation.
Sample Answer
Direct answer
Catch an exception locally only when you can actually do something useful with it there (retry, fall back, translate it into a domain-specific error); otherwise let it propagate. Create a custom exception type when the caller needs to distinguish this failure from others programmatically; reuse a generic one when nobody downstream will branch on it.
Structured elaboration
- The 'can I do something' test: at each layer, ask whether you have enough context AND enough authority to resolve the failure. A repository layer that hits a broken connection can retry once; it usually can't decide whether the caller should show an error page or silently use cached data, so it should propagate (possibly wrapped) rather than swallow.
- Custom vs generic exceptions: define a custom type when a caller three layers up needs to branch (
except PaymentDeclinedError: offer another cardvsexcept PaymentGatewayTimeout: retry). A genericRuntimeErroror bareExceptionis fine for truly unexpected states nobody is meant to handle specially, but never use a bareexcept Exception:as a catch-all that discards the distinction. - Avoiding pitfalls: never catch-and-discard (
except Exception: pass) without at minimum logging with full context; never catch a broad type just to re-raise the same thing unchanged (that's dead code that hides which specific failures the layer actually expects); when you DO catch to translate, preserve the original exception as the cause (raise DatabaseError(...) from ein Python, wrapping in Java) so a debugger can still walk to the root cause. Also avoid duplicating log lines at every layer: if every layer that catches-and-rethrows also logs the same exception on its way up, one real failure produces several near-identical log entries by the time it reaches the top, which pages on-call with noisy duplicates and makes the true error rate impossible to read off log volume. The fix is to log ONCE, at the layer that either fully handles the error or is the outermost boundary (the request handler, the job runner), and let every intermediate layer that only wraps-and-rethrows do so silently, relying on the exception chain (from e) rather than a fresh log line to preserve context.
Worked example
Service-to-service call: a UserService.get_profile(id) calls an HTTP client that can raise ConnectionError or HTTPStatusError. UserService catches both, and translates HTTPStatusError with status 404 into its own UserNotFoundError (a real domain concept the caller branches on), but lets a 500 or ConnectionError propagate wrapped as UserServiceUnavailableError from e (preserving the cause) since it has no way to fix an unreachable dependency itself; it does NOT log at this layer, since it's not the final decision point.
Database operation: a repository's save(record) catches a unique-constraint violation and translates it to DuplicateRecordError (a business-meaningful case the caller likely wants to show the user), but lets a connection-pool-exhausted error propagate unmodified up to the request-handling layer, which is the only layer with enough context to decide 'shed load' vs 'retry', and is also the only layer that logs it.
Trade-offs and pitfalls
Over-translating (wrapping every low-level exception in a new custom type at every layer) produces an exception-type explosion that is as hard to reason about as no typing at all, and it can silently lose the original stack trace if you forget to chain the cause. Under-translating (letting raw library exceptions like ConnectionError leak all the way to a UI layer) forces every caller to know implementation details of a dependency two layers down. The right amount of translation happens at trust/ownership boundaries (crossing into a new bounded context, crossing a network call, crossing into user-facing code), not at every function call, and the same discipline applies to logging: log at the boundary that owns the decision, not reflexively at every catch block.
Describe the role of an Ingress resource versus an Ingress Controller in Kubernetes. What does the Ingress object itself declare, what does the controller actually do with that declaration, and why does Kubernetes split the responsibility this way instead of having one object do both?
Sample Answer
An Ingress object declares what HTTP(S) routing should happen (hostnames, path rules, which Service backs each path, which TLS secret to use); an Ingress Controller is the running component that watches Ingress objects and actually implements that routing on real infrastructure. Kubernetes splits these into two objects for the same reason it splits a Deployment's spec from the controller that reconciles it: the API object stays a stable, portable declaration, while the implementation (which varies enormously between environments) is free to be swapped out without changing what you wrote.
What the Ingress object itself declares
An Ingress is pure declaration, no execution: a list of host/path rules, each pointing at a backend Service and port, plus optional TLS configuration referencing a Secret containing a certificate and key. It has no opinion about how that routing gets enforced; by itself, an Ingress object sitting in the API server does nothing.
What the Ingress Controller does with it
The controller (for example nginx-ingress, Traefik, or a cloud provider's own controller such as GKE's or AGIC for Azure) watches for Ingress objects and translates the declared rules into a real, running configuration: it opens listener ports, terminates TLS using the referenced Secret, and applies the host/path routing logic, typically by configuring an underlying proxy (like nginx) or provisioning a cloud load balancer.
Why split the two, contrasted with a Service of type LoadBalancer
A Service of type LoadBalancer works at L4 (Layer 4, the TCP/UDP transport layer): it exposes one Service on one IP and port, with no visibility into HTTP hostnames or paths. Ingress works at L7 (Layer 7, the application layer): it can route many hostnames and paths to many different backend Services through a single entry point, but only because something understands HTTP well enough to look inside the request to make that decision, which is exactly the controller's job.
| Ingress object | Ingress Controller | |
|---|---|---|
| What it is | A declarative API object | A running workload/process |
| What it knows | Routing intent: hosts, paths, TLS references | How to actually enforce that intent on real infrastructure |
| Portability | The same Ingress YAML can, in principle, work with any controller | Controller-specific behavior (annotations, feature support) varies significantly |
| Analogy | A restaurant's order ticket | The kitchen that actually cooks the order |
Why split the responsibility this way
- No single "correct" implementation exists. Different environments need genuinely different routing implementations (self-hosted nginx, a cloud provider's managed load balancer, a service mesh's gateway); a single hardcoded Ingress-to-infrastructure mapping baked into the API server couldn't serve all of them.
- The API object stays stable across environments. The same Ingress manifest can move between a local cluster running nginx-ingress and a cloud cluster running a managed controller, changing only which controller is installed, not the application team's YAML.
- It matches Kubernetes' general controller pattern. Objects declare desired state; a controller reconciles that state against reality. Ingress is just this pattern applied to L7 routing, the same separation Kubernetes already uses everywhere else (a Deployment declares desired replica state, the Deployment controller makes it real).
Trade-offs and pitfalls
- Because the controller does the real work, its feature set and its vendor-specific annotations determine what's actually possible; two clusters running different controllers can behave differently from the exact same Ingress YAML, which undermines the portability the split is meant to provide unless you stick to well-supported, portable fields.
- No Ingress Controller installed means Ingress objects sit inert; a common early mistake is writing correct Ingress rules and then wondering why nothing routes, when the real gap is a missing or misconfigured controller.
- Cross-cutting concerns that need to apply before traffic even reaches a specific controller instance (global rate limiting, a shared web application firewall) are often better handled at an edge layer in front of the cluster rather than pushed entirely into per-Ingress annotations.
Two people you mentor are in conflict with each other, and it's starting to affect the team's work. How do you handle it?
Sample Answer
Direct answer
Talk to each person privately before bringing them together, so you understand the facts and stakes from each side without an audience. Then classify the conflict as substantive (a genuine disagreement about the right call) versus interpersonal (friction dressed up as a substantive disagreement), because each needs a different resolution path. Bring them together around a shared goal and concrete evidence, not around who's right, and if it's genuinely undecidable in the room, use a time-boxed way to get more evidence rather than let the standoff continue to block the team.
Resolution framework
Never mediate cold in a group. Talk to each person separately first. You're listening for their read of the facts, what they think is at stake, and what "winning" would actually look like to them. This also surfaces things people won't say in front of the other person.
Classify before you intervene. A disagreement that looks technical or process-based on the surface is sometimes substantive and sometimes really about communication style or unresolved friction. Treating an interpersonal conflict as if it just needs more evidence wastes everyone's time; treating a real substantive disagreement as if it just needs better feelings management does too.
Reframe the joint conversation around the shared goal. Ask both people directly what evidence would change their mind. This shifts the conversation from defending a position to examining what's actually true, and it's a useful tell: someone who can't answer that question may be more attached to being right than to the outcome.
Use a time-boxed way to break a genuine deadlock. If the disagreement is real and evidence-based but neither side has enough information to concede, propose a small, bounded experiment or spike to settle it rather than let the argument continue indefinitely. If there's no time for that, make the call yourself and say plainly that you're doing so.
Follow through explicitly. Name who owns the resulting decision, document it somewhere durable, and check back in later to make sure the resolution actually held rather than just went quiet.
Worked example
Two people you mentor are at an impasse over a decision, and delivery is now stalled because of it. Separate conversations reveal the disagreement is mostly substantive, but there's real interpersonal friction layered on top, one of them has started talking over the other in shared meetings. You facilitate a joint session with explicit ground rules, focused on what evidence would resolve the substantive question, and propose a short timeboxed way to get that evidence rather than debate it further. Separately, and privately, you have a direct conversation with the person who'd been talking over the other about how that was landing on the team, independent of who turns out to be right on the substance.
Trade-offs and pitfalls
Mediating in a group before talking to each person privately risks blindsiding someone and getting performative, professional-sounding answers that hide what's actually going on.
Always pushing for consensus wastes time on disagreements that genuinely don't have a consensus answer. Sometimes the right move is a clean, owned decision, not more discussion.
Making the call yourself resolves the immediate block but has a cost: it can create resentment, or teach people to escalate disagreements to you instead of learning to resolve them with each other, so it's worth being deliberate about when you step in to decide versus when you keep facilitating.
A conflict that keeps recurring in slightly different forms is often a signal of a structural problem, unclear ownership boundaries between the two people, rather than a personality clash, and treating the symptom each time without noticing the pattern means you'll be back here again.
Recommended Additional Resources
- The Site Reliability Workbook by Google (covers monitoring, incident response, automation)
- Kubernetes the Hard Way by Kelsey Hightower (deep understanding of container orchestration)
- LeetCode (for scripting and algorithm refresher; focus on string manipulation, file I/O, system simulation problems)
- System Design Primer (GitHub repo) - focus on foundational components like load balancers, caches, databases, monitoring
- Google Cloud Architecture Center and AWS Well-Architected Framework (real-world architecture patterns)
- Post-mortems from Google, Netflix, and Etsy (blameless incident analysis and SRE thinking)
- Bash Guide for Beginners and Python documentation (for scripting proficiency)
- Kubernetes official documentation, especially troubleshooting guide and pod lifecycle
- Prometheus and Grafana documentation (modern monitoring stack fundamentals)
- Container and container orchestration courses (Udemy, Coursera) to strengthen Docker and Kubernetes understanding
- Blogs: Google Cloud Blog, Netflix Tech Blog, AWS Architecture Blog, and individual SRE practitioner blogs
- Practice setting up a local Kubernetes cluster (minikube, kind) and deploying applications with different failure modes to practice troubleshooting
Search Results
Google SRE NALS (Non-Abstract Large Systems Design) Round ...
... junior devops engineer interview questions devops aws interview questions ... Site Reliability Engineer (SRE) Interview: Real Questions & Expert Answers!
Top 50+ Software Engineering Interview Questions and Answers
1. What are the Characteristics of Software? · Functionality: It refers to the software performance compared to the purpose it was created for. · Reliability: It ...
30+ Software Engineer Interview Questions: What to Expect & How ...
Whether you're hiring for a junior, mid-level, or senior position, this guide walks you through 30+ software engineer interview questions, organized by category ...
Top 110+ DevOps Interview Questions and Answers for 2026
Here are some of the most common DevOps interview questions and answers that can help you while you prepare for DevOps roles in the industry.
30 Site Reliability Engineer Interview Questions to Ask Candidates
How do you communicate reliability metrics and risks to non-technical stakeholders? What motivates you about being an SRE? How do you balance urgent ...
Top Google Interview Questions for Software Engineers (2024)
The Google interview questions for software engineers are focused on three topics: algorithms, data structures, and distributed system design.
This interview preparation guide was generated using AI-powered research from the sources listed above. While we strive for accuracy, we recommend verifying critical information from official company sources.
Want to create your own tailored preparation guide using our deep research?
Get Started for FreeInterview-Ready Courses
Visual-first, interactive, structured learning paths
Browse Site Reliability Engineer (SRE) jobs
AI-enriched listings across hundreds of company career pages
Explore Jobs