📊 SQL SATURDAY #2 - JOINs Without the Confusion
Two tables this week:
Notice Charlie has no orders.
INNER JOIN - only rows that match in both tables:
Charlie won't appear - he has no matching order.
LEFT JOIN - all rows from the left table, matched or not:
Charlie appears with
⚠️ Interview trap: "Find customers with zero orders."
People often try
Which JOIN type trips you up the most? RIGHT and FULL OUTER are coming in a few weeks 👀
Two tables this week:
customers orders
+----+---------+ +----+-------------+--------+
| id | name | | id | customer_id | amount |
+----+---------+ +----+-------------+--------+
| 1 | Alice | | 1 | 1 | 250 |
| 2 | Bob | | 2 | 1 | 100 |
| 3 | Charlie | | 3 | 2 | 75 |
+----+---------+ +----+-------------+--------+
Notice Charlie has no orders.
INNER JOIN - only rows that match in both tables:
sql
SELECT c.name, o.amount
FROM customers c
INNER JOIN orders o ON c.id = o.customer_id;
Charlie won't appear - he has no matching order.
LEFT JOIN - all rows from the left table, matched or not:
sql
SELECT c.name, o.amount
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id;
Charlie appears with
amount = NULL.⚠️ Interview trap: "Find customers with zero orders."
sql
SELECT c.name
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
WHERE o.id IS NULL;
People often try
WHERE o.amount = 0 here - wrong, that finds orders worth $0, not customers with no orders at all. Filtering on IS NULL after a LEFT JOIN is the pattern to remember.Which JOIN type trips you up the most? RIGHT and FULL OUTER are coming in a few weeks 👀
🧠 EDUCATIONAL CS #2 - Why Hash Tables Are Basically Magic
You use hash tables constantly (Python dicts, JS objects, Java HashMaps) - but do you know why they're O(1)?
Here's the core idea:
1️⃣ You have a hash function that takes a key and turns it into a number (an index).
2️⃣ That index points directly to a slot ("bucket") in an array.
3️⃣ To look up a value, you hash the key again, jump straight to that slot - no searching required.
That's why lookup, insert, and delete are all O(1) on average.
Why "on average" and not always? Because two different keys can hash to the same index - a collision. When that happens, most implementations chain multiple entries in the same bucket (a small linked list) or probe for the next open slot.
If your hash function is bad and everything collides into one bucket, your "O(1)" hash table quietly degrades into an O(n) linked list. This is exactly why interviewers sometimes ask: "what happens if all your keys hash to the same value?"
Now you know the answer. 😉
What's a bug you've hit because of hash collisions or bad hashing? 👇
You use hash tables constantly (Python dicts, JS objects, Java HashMaps) - but do you know why they're O(1)?
Here's the core idea:
1️⃣ You have a hash function that takes a key and turns it into a number (an index).
2️⃣ That index points directly to a slot ("bucket") in an array.
3️⃣ To look up a value, you hash the key again, jump straight to that slot - no searching required.
key "apple" → hash("apple") → index 7 → array[7] = value
That's why lookup, insert, and delete are all O(1) on average.
Why "on average" and not always? Because two different keys can hash to the same index - a collision. When that happens, most implementations chain multiple entries in the same bucket (a small linked list) or probe for the next open slot.
If your hash function is bad and everything collides into one bucket, your "O(1)" hash table quietly degrades into an O(n) linked list. This is exactly why interviewers sometimes ask: "what happens if all your keys hash to the same value?"
Now you know the answer. 😉
What's a bug you've hit because of hash collisions or bad hashing? 👇
💬 DISCUSSION - What's Your Interview Horror Story?
We've all got one. The question that made your brain completely blank. The moment you realized you'd been debugging the wrong function for 10 minutes. The interviewer who just... stared at you in silence.
Drop your worst interview moment below. No judgment - half the people reading this have a story just as bad (including me).
Bonus points if it has a happy ending. 😄
We've all got one. The question that made your brain completely blank. The moment you realized you'd been debugging the wrong function for 10 minutes. The interviewer who just... stared at you in silence.
Drop your worst interview moment below. No judgment - half the people reading this have a story just as bad (including me).
Bonus points if it has a happy ending. 😄
To effectively learn SQL for a Data Analyst role, follow these steps:
1. Start with a basic course:
Begin by taking a basic course on YouTube to familiarize yourself with SQL syntax and terminologies. I recommend the "Learn Complete SQL" playlist from the "techTFQ" YouTube channel.
2. Practice syntax and commands:
As you learn new terminologies from the course, practice their syntax on the "w3schools" website. This site provides clear examples of SQL syntax, commands, and functions.
3. Solve practice questions:
After completing the initial steps, start solving easy-level SQL practice questions on platforms like "Hackerrank," "Leetcode," "Datalemur," and "Stratascratch." If you get stuck, use the discussion forums on these platforms or ask ChatGPT for help. You can paste the problem into ChatGPT and use a prompt like:
- "Explain the step-by-step solution to the above problem as I am new to SQL, also explain the solution as per the order of execution of SQL."
4. Gradually increase difficulty:
Gradually move on to more difficult practice questions. If you encounter new SQL concepts, watch YouTube videos on those topics or ask ChatGPT for explanations.
5. Consistent practice:
The most crucial aspect of learning SQL is consistent practice. Regular practice will help you build and solidify your skills.
By following these steps and maintaining regular practice, you'll be well on your way to mastering SQL for a Data Analyst role.
1. Start with a basic course:
Begin by taking a basic course on YouTube to familiarize yourself with SQL syntax and terminologies. I recommend the "Learn Complete SQL" playlist from the "techTFQ" YouTube channel.
2. Practice syntax and commands:
As you learn new terminologies from the course, practice their syntax on the "w3schools" website. This site provides clear examples of SQL syntax, commands, and functions.
3. Solve practice questions:
After completing the initial steps, start solving easy-level SQL practice questions on platforms like "Hackerrank," "Leetcode," "Datalemur," and "Stratascratch." If you get stuck, use the discussion forums on these platforms or ask ChatGPT for help. You can paste the problem into ChatGPT and use a prompt like:
- "Explain the step-by-step solution to the above problem as I am new to SQL, also explain the solution as per the order of execution of SQL."
4. Gradually increase difficulty:
Gradually move on to more difficult practice questions. If you encounter new SQL concepts, watch YouTube videos on those topics or ask ChatGPT for explanations.
5. Consistent practice:
The most crucial aspect of learning SQL is consistent practice. Regular practice will help you build and solidify your skills.
By following these steps and maintaining regular practice, you'll be well on your way to mastering SQL for a Data Analyst role.
🏗️ SYSTEM DESIGN MONDAY #2 - Caching 101
Last week: client → server → database. Now let's fix the bottleneck.
Say your database gets hit with the same query a thousand times a second - like fetching a popular product page. Hitting disk every time is wasteful.
Enter the cache: a fast, in-memory layer that sits between your server and database.
Flow:
1️⃣ Server checks cache first
2️⃣ Cache hit → return immediately (fast!)
3️⃣ Cache miss → query database, store result in cache, return it
Popular tools: Redis, Memcached.
Two concepts you MUST be able to explain in an interview:
🔹 Cache eviction (LRU) - cache has limited memory, so when it's full, Least Recently Used items get kicked out to make room for new ones.
🔹 Cache invalidation - the hardest part. If the underlying data changes, how does the cache know to update? (Famous quote: "There are only two hard things in computer science: cache invalidation and naming things.")
Common strategies: TTL (time-to-live expiry), write-through (update cache and DB together), or explicit invalidation on writes.
Next System Design Monday: what happens when ONE server can't handle the traffic anymore - load balancing.
What would you cache first in a system like Instagram? 👇
Last week: client → server → database. Now let's fix the bottleneck.
Say your database gets hit with the same query a thousand times a second - like fetching a popular product page. Hitting disk every time is wasteful.
Enter the cache: a fast, in-memory layer that sits between your server and database.
[Client] → [Server] → [Cache] → [Database]
↑
(checked first)
Flow:
1️⃣ Server checks cache first
2️⃣ Cache hit → return immediately (fast!)
3️⃣ Cache miss → query database, store result in cache, return it
Popular tools: Redis, Memcached.
Two concepts you MUST be able to explain in an interview:
🔹 Cache eviction (LRU) - cache has limited memory, so when it's full, Least Recently Used items get kicked out to make room for new ones.
🔹 Cache invalidation - the hardest part. If the underlying data changes, how does the cache know to update? (Famous quote: "There are only two hard things in computer science: cache invalidation and naming things.")
Common strategies: TTL (time-to-live expiry), write-through (update cache and DB together), or explicit invalidation on writes.
Next System Design Monday: what happens when ONE server can't handle the traffic anymore - load balancing.
What would you cache first in a system like Instagram? 👇
🐛 SPOT THE BUG #2
Language: Java
What breaks under concurrent access? 👇
.
.
.
The bug:
Fixed version:
Alternative fix: mark
This is one of the most common concurrency bugs in real production systems, not just interviews. Ever debugged something like this in the wild? 👇
Language: Java
java
public class Counter {
private int count;
public void increment() {
count++;
}
public int getCount() {
return count;
}
}
// Used across 10 threads simultaneously calling increment()
What breaks under concurrent access? 👇
.
.
.
The bug:
count++ is NOT atomic. It's actually three operations: read, increment, write. Two threads can read the same value, both increment it, and both write back the same result - losing an update. With 10 threads hammering this, your final count will almost always be less than expected.Fixed version:
java
public class Counter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}
public int getCount() {
return count.get();
}
}
Alternative fix: mark
increment() as synchronized, though that's slower under high contention than AtomicInteger.This is one of the most common concurrency bugs in real production systems, not just interviews. Ever debugged something like this in the wild? 👇
🎯 CODING CHALLENGE #3 - Reverse a Linked List
Difficulty: Easy-Medium | Asked at: Amazon, Apple, Adobe
Reverse a singly linked list, iteratively.
💡 Hint: You need to track three pointers as you walk the list: the previous node, the current node, and the next node - because once you flip a pointer, you lose the way forward unless you saved it first.
Solution:
Complexity: O(n) time, O(1) space - this is the detail that separates a strong answer from an average one. A recursive solution is O(n) time but O(n) space due to the call stack - know both, and be ready to explain the tradeoff.
Common mistake: Forgetting to save
Iterative or recursive - which do you reach for first, and why? 👇
Difficulty: Easy-Medium | Asked at: Amazon, Apple, Adobe
Reverse a singly linked list, iteratively.
Input: 1 → 2 → 3 → 4 → None
Output: 4 → 3 → 2 → 1 → None
💡 Hint: You need to track three pointers as you walk the list: the previous node, the current node, and the next node - because once you flip a pointer, you lose the way forward unless you saved it first.
Solution:
python
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def reverse_list(head):
prev = None
curr = head
while curr:
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node
return prev
Complexity: O(n) time, O(1) space - this is the detail that separates a strong answer from an average one. A recursive solution is O(n) time but O(n) space due to the call stack - know both, and be ready to explain the tradeoff.
Common mistake: Forgetting to save
curr.next before overwriting it, which permanently disconnects the rest of the list.Iterative or recursive - which do you reach for first, and why? 👇
❤1
🗣️ BEHAVIORAL INTERVIEW #2 - "Tell Me About a Time You Failed"
This question isn't a trap to expose your weaknesses. It's testing whether you're self-aware and whether you actually learn from mistakes.
❌ What kills this answer:
- "I don't really have failures, I'm pretty thorough" (nobody believes this, and it reads as low self-awareness)
- Choosing a failure that was actually someone else's fault
- Never getting to what you learned
✅ The STAR-based structure that works:
Situation: Brief context.
Task: What you were responsible for.
Action: What YOU did (own it, don't blame the team).
Result: What happened, AND what you changed afterward.
Example:
"I once shipped a database migration without adequately testing it against production-scale data. It caused a 20-minute outage during peak hours. I immediately rolled it back, then led the postmortem. The real failure wasn't the bug - it was that we didn't have a staging environment that mirrored production data volume. I pushed for building one, and we haven't had a similar incident since."
Notice: real mistake, real ownership, real systemic fix. That's what "failure" questions are actually testing.
What's a failure you'd feel comfortable sharing in an interview? (Only share what you're comfortable with, of course) 👇
This question isn't a trap to expose your weaknesses. It's testing whether you're self-aware and whether you actually learn from mistakes.
❌ What kills this answer:
- "I don't really have failures, I'm pretty thorough" (nobody believes this, and it reads as low self-awareness)
- Choosing a failure that was actually someone else's fault
- Never getting to what you learned
✅ The STAR-based structure that works:
Situation: Brief context.
Task: What you were responsible for.
Action: What YOU did (own it, don't blame the team).
Result: What happened, AND what you changed afterward.
Example:
"I once shipped a database migration without adequately testing it against production-scale data. It caused a 20-minute outage during peak hours. I immediately rolled it back, then led the postmortem. The real failure wasn't the bug - it was that we didn't have a staging environment that mirrored production data volume. I pushed for building one, and we haven't had a similar incident since."
Notice: real mistake, real ownership, real systemic fix. That's what "failure" questions are actually testing.
What's a failure you'd feel comfortable sharing in an interview? (Only share what you're comfortable with, of course) 👇
❤1
🕵️ RECRUITER SECRETS #2 - The "Culture Fit" Question Nobody Explains
When a recruiter says "we're assessing culture fit," most candidates hear "do they like me personally." That's not quite it.
What they're actually assessing:
✅ Do you ask questions, or do you passively wait to be told what to do?
✅ How do you talk about former teammates and managers? (Bad-mouthing a previous employer is a massive red flag - even if they were genuinely bad)
✅ Do you show curiosity about the company's actual problems, or just want "a job"?
✅ Can you disagree with someone respectfully, or do you either fold immediately or get defensive?
Here's the secret: culture fit interviews are often scored on specific behavioral traits the company has defined internally (ownership, collaboration, communication) - not vibes. Prepare a story for each of these, not just "tell me about yourself."
One tip that works surprisingly well: ask your interviewer "what does someone who's thriving on this team actually do day-to-day?" It shows genuine interest and gives you real signal about whether you'd enjoy the role.
What's the strangest "culture fit" question you've ever been asked? 👇
When a recruiter says "we're assessing culture fit," most candidates hear "do they like me personally." That's not quite it.
What they're actually assessing:
✅ Do you ask questions, or do you passively wait to be told what to do?
✅ How do you talk about former teammates and managers? (Bad-mouthing a previous employer is a massive red flag - even if they were genuinely bad)
✅ Do you show curiosity about the company's actual problems, or just want "a job"?
✅ Can you disagree with someone respectfully, or do you either fold immediately or get defensive?
Here's the secret: culture fit interviews are often scored on specific behavioral traits the company has defined internally (ownership, collaboration, communication) - not vibes. Prepare a story for each of these, not just "tell me about yourself."
One tip that works surprisingly well: ask your interviewer "what does someone who's thriving on this team actually do day-to-day?" It shows genuine interest and gives you real signal about whether you'd enjoy the role.
What's the strangest "culture fit" question you've ever been asked? 👇
⚠️ COMMON INTERVIEW MISTAKE #2 - Going Silent While Coding
Interviewers aren't just grading your final code. They're grading how you think.
If you go completely silent for 5 minutes while typing, the interviewer has zero signal about your thought process - and silence under pressure often reads as "stuck" even when you're not.
✅ What to do instead - narrate as you go:
"I'm going to start by handling the edge case where the array is empty."
"I'm using a dictionary here so I get O(1) lookups instead of scanning the array again."
"Let me trace through this with the example to make sure it's correct before I move on."
This isn't about talking nonstop - brief, purposeful narration. It turns a silent black box into a conversation, and it gives the interviewer chances to nudge you in the right direction if you're drifting off track (which they usually WANT to do - most interviewers are rooting for you).
Do you naturally talk while coding, or does it feel forced? Genuinely curious 👇
Interviewers aren't just grading your final code. They're grading how you think.
If you go completely silent for 5 minutes while typing, the interviewer has zero signal about your thought process - and silence under pressure often reads as "stuck" even when you're not.
✅ What to do instead - narrate as you go:
"I'm going to start by handling the edge case where the array is empty."
"I'm using a dictionary here so I get O(1) lookups instead of scanning the array again."
"Let me trace through this with the example to make sure it's correct before I move on."
This isn't about talking nonstop - brief, purposeful narration. It turns a silent black box into a conversation, and it gives the interviewer chances to nudge you in the right direction if you're drifting off track (which they usually WANT to do - most interviewers are rooting for you).
Do you naturally talk while coding, or does it feel forced? Genuinely curious 👇
🎯 CODING CHALLENGE #4 - Merge Intervals
Difficulty: Medium | Asked at: Meta, Google, LinkedIn
Given a list of intervals, merge all overlapping ones.
💡 Hint: Overlaps are much easier to spot once the intervals are sorted by start time.
Solution:
Complexity: O(n log n) - dominated by the sort. The merge pass itself is O(n).
Common mistake: Forgetting
This pattern (sort, then single pass comparing to the last processed item) shows up in a TON of interval problems. Recognize it and you'll fly through similar questions.
What's your go-to strategy when you see "intervals" in a problem? 👇
Difficulty: Medium | Asked at: Meta, Google, LinkedIn
Given a list of intervals, merge all overlapping ones.
Input: [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
💡 Hint: Overlaps are much easier to spot once the intervals are sorted by start time.
Solution:
python
def merge(intervals):
intervals.sort(key=lambda x: x[0])
merged = [intervals[0]]
for start, end in intervals[1:]:
last_end = merged[-1][1]
if start <= last_end:
merged[-1][1] = max(last_end, end)
else:
merged.append([start, end])
return merged
Complexity: O(n log n) - dominated by the sort. The merge pass itself is O(n).
Common mistake: Forgetting
max(last_end, end) and just assuming end is always bigger. Consider [[1,10],[2,3]] - the second interval is fully contained in the first, so if you don't take the max, you'd shrink your merged interval incorrectly.This pattern (sort, then single pass comparing to the last processed item) shows up in a TON of interval problems. Recognize it and you'll fly through similar questions.
What's your go-to strategy when you see "intervals" in a problem? 👇
📊 SQL SATURDAY #3 - GROUP BY and Aggregates
Question: Find the total spend per customer, only for customers who spent more than $150 total.
⚠️ The classic trap: using
Simple rule to remember: WHERE filters rows, HAVING filters groups.
What SQL clause order still confuses you sometimes? (No shame - even senior engineers mix this up under pressure) 👇
orders
+----+-------------+--------+------------+
| id | customer_id | amount | order_date |
+----+-------------+--------+------------+
| 1 | 1 | 250 | 2024-01-05 |
| 2 | 1 | 100 | 2024-02-14 |
| 3 | 2 | 75 | 2024-01-20 |
| 4 | 3 | 500 | 2024-03-01 |
| 5 | 2 | 200 | 2024-03-15 |
Question: Find the total spend per customer, only for customers who spent more than $150 total.
sql
SELECT customer_id, SUM(amount) AS total_spent
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 150;
⚠️ The classic trap: using
WHERE instead of HAVING here.sql
-- WRONG:
SELECT customer_id, SUM(amount) AS total_spent
FROM orders
WHERE SUM(amount) > 150 -- ❌ ERROR
GROUP BY customer_id;
WHERE filters rows before grouping happens - it has no idea what SUM(amount) even means yet, since that's calculated during grouping. HAVING filters after the aggregation, which is exactly what you need for conditions on aggregate functions.Simple rule to remember: WHERE filters rows, HAVING filters groups.
What SQL clause order still confuses you sometimes? (No shame - even senior engineers mix this up under pressure) 👇
❤1
📄 RESUME ROAST #2
Real-style bullet incoming:
> "Familiar with Python, Java, C++, JavaScript, React, Angular, Vue, Node.js, Docker, Kubernetes, AWS, Azure, GCP, MongoDB, PostgreSQL, Redis, Kafka, GraphQL"
What's wrong here? 👇
.
.
.
The roast:
This is the "keyword salad" resume. It signals one of two things to an experienced hiring manager: either you're exaggerating your depth in most of these, or you genuinely have surface-level exposure to 20 tools and mastery of none.
Recruiters and hiring managers both find this to be a red flag, not a strength.
✅ Better approach: List 4-6 technologies you can genuinely go deep on in an interview, and organize by proficiency if you must list more:
> "Core: Python, PostgreSQL, AWS (EC2, S3, Lambda)
> Familiar: Docker, Kafka, GraphQL"
Anything on your resume, you should be able to talk about for 10 minutes without panicking. If you can't, it doesn't belong in your top skills section.
Be honest - is there something on your resume right now you'd struggle to explain in depth? 😅
Real-style bullet incoming:
> "Familiar with Python, Java, C++, JavaScript, React, Angular, Vue, Node.js, Docker, Kubernetes, AWS, Azure, GCP, MongoDB, PostgreSQL, Redis, Kafka, GraphQL"
What's wrong here? 👇
.
.
.
The roast:
This is the "keyword salad" resume. It signals one of two things to an experienced hiring manager: either you're exaggerating your depth in most of these, or you genuinely have surface-level exposure to 20 tools and mastery of none.
Recruiters and hiring managers both find this to be a red flag, not a strength.
✅ Better approach: List 4-6 technologies you can genuinely go deep on in an interview, and organize by proficiency if you must list more:
> "Core: Python, PostgreSQL, AWS (EC2, S3, Lambda)
> Familiar: Docker, Kafka, GraphQL"
Anything on your resume, you should be able to talk about for 10 minutes without panicking. If you can't, it doesn't belong in your top skills section.
Be honest - is there something on your resume right now you'd struggle to explain in depth? 😅
This media is not supported in your browser
VIEW IN TELEGRAM
Sorting Algortihm Comparison
🏗️ SYSTEM DESIGN MONDAY #3 - Load Balancing & Horizontal Scaling
One server is now overwhelmed. Two options: make it bigger (vertical scaling) or add more of them (horizontal scaling). Horizontal scaling is what most large systems actually do - there's a ceiling on how big one machine can get, but no real ceiling on how many machines you can add.
The load balancer sits in front of your servers and distributes incoming requests, usually via:
🔹 Round robin - requests go to servers in rotating order
🔹 Least connections - send to whichever server currently has the fewest active requests
🔹 IP hash - same client always routed to the same server (useful for session data)
Here's the important follow-up question interviewers ask: "if a user's session data is stored in Server 2's memory, what happens if the load balancer routes their next request to Server 3?"
That's the concept of statelessness - well-designed servers shouldn't hold session data locally at all. Instead, store session state in a shared cache (like Redis) or a database, so ANY server can handle ANY request. This is a foundational principle behind horizontally scalable systems.
Why do you think "statelessness" matters so much in distributed systems? 👇
One server is now overwhelmed. Two options: make it bigger (vertical scaling) or add more of them (horizontal scaling). Horizontal scaling is what most large systems actually do - there's a ceiling on how big one machine can get, but no real ceiling on how many machines you can add.
┌─────────┐
┌─────▶│ Server 1│
│ └─────────┘
[Client] → [Load Balancer]
│ ┌─────────┐
├─────▶│ Server 2│
│ └─────────┘
│ ┌─────────┐
└─────▶│ Server 3│
└─────────┘
The load balancer sits in front of your servers and distributes incoming requests, usually via:
🔹 Round robin - requests go to servers in rotating order
🔹 Least connections - send to whichever server currently has the fewest active requests
🔹 IP hash - same client always routed to the same server (useful for session data)
Here's the important follow-up question interviewers ask: "if a user's session data is stored in Server 2's memory, what happens if the load balancer routes their next request to Server 3?"
That's the concept of statelessness - well-designed servers shouldn't hold session data locally at all. Instead, store session state in a shared cache (like Redis) or a database, so ANY server can handle ANY request. This is a foundational principle behind horizontally scalable systems.
Why do you think "statelessness" matters so much in distributed systems? 👇
💰 SALARY NEGOTIATION #2 - Handling "What's Your Current Salary?"
This question puts a lot of candidates on the spot - and in many US states, it's actually illegal for employers to ask. But it still comes up, especially in phone screens or in regions where it's legal.
The problem with answering directly: it anchors your new offer to your old salary, especially if you were underpaid before.
✅ A script that redirects gracefully:
"I'd rather focus on the value I can bring to this role and what's a fair market rate for it, rather than my previous compensation, which honestly reflected a different set of circumstances. Based on my research, I'm looking at a range of $X to $Y for this role - does that align with your budget?"
If they push:
"I understand you're trying to gauge fit - I'm confident that whatever we agree on will be fair market rate for the role and my experience level. What's the budgeted range for this position?"
Turning the question back on THEM to share the range first is a classic, effective negotiation tactic - whoever names a number first gives up information.
Have you ever been asked this? How did you handle it? 👇
This question puts a lot of candidates on the spot - and in many US states, it's actually illegal for employers to ask. But it still comes up, especially in phone screens or in regions where it's legal.
The problem with answering directly: it anchors your new offer to your old salary, especially if you were underpaid before.
✅ A script that redirects gracefully:
"I'd rather focus on the value I can bring to this role and what's a fair market rate for it, rather than my previous compensation, which honestly reflected a different set of circumstances. Based on my research, I'm looking at a range of $X to $Y for this role - does that align with your budget?"
If they push:
"I understand you're trying to gauge fit - I'm confident that whatever we agree on will be fair market rate for the role and my experience level. What's the budgeted range for this position?"
Turning the question back on THEM to share the range first is a classic, effective negotiation tactic - whoever names a number first gives up information.
Have you ever been asked this? How did you handle it? 👇
🧠 EDUCATIONAL CS #3 - Recursion Without the Headache
Recursion clicks once you stop thinking about "the whole problem" and start thinking about these two things:
1️⃣ Base case - the simplest version of the problem you can answer directly, no further recursion needed.
2️⃣ Recursive case - how to break the problem into a smaller version of itself, plus some work.
Here's the trick most people miss: you don't need to mentally trace the ENTIRE call stack to trust recursion works. You just need to trust that
⚠️ Common failure mode: forgetting the base case, or having a recursive case that doesn't actually move toward it - both cause infinite recursion and a stack overflow.
Also worth knowing for interviews: every recursive solution can be rewritten iteratively (usually with an explicit stack), and interviewers sometimes ask you to do exactly that, to test whether you understand what recursion is doing under the hood rather than treating it as magic.
What's the recursion problem that finally made it click for you? 👇
Recursion clicks once you stop thinking about "the whole problem" and start thinking about these two things:
1️⃣ Base case - the simplest version of the problem you can answer directly, no further recursion needed.
2️⃣ Recursive case - how to break the problem into a smaller version of itself, plus some work.
python
def factorial(n):
if n == 0: # base case
return 1
return n * factorial(n - 1) # recursive case
Here's the trick most people miss: you don't need to mentally trace the ENTIRE call stack to trust recursion works. You just need to trust that
factorial(n-1) correctly returns (n-1)!, because you already proved the base case works, and each recursive call is just one step closer to it. This is called "trusting the recursion."⚠️ Common failure mode: forgetting the base case, or having a recursive case that doesn't actually move toward it - both cause infinite recursion and a stack overflow.
Also worth knowing for interviews: every recursive solution can be rewritten iteratively (usually with an explicit stack), and interviewers sometimes ask you to do exactly that, to test whether you understand what recursion is doing under the hood rather than treating it as magic.
What's the recursion problem that finally made it click for you? 👇
❤1
🐛 SPOT THE BUG #3
Language: Python
Subtle one. Spot it before scrolling 👇
.
.
.
The bug: Infinite loop risk. When
Fixed version:
This is exactly why binary search is famously easy to get "almost right" but subtly wrong. Off-by-one errors here are so common that some engineers recommend writing out the invariant explicitly ("left is always a possible answer, right is always excluded") before coding it.
Do you write binary search from memory, or always double-check the boundaries? 👇
Language: Python
python
def binary_search(arr, target):
left, right = 0, len(arr)
while left < right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid
else:
right = mid
return -1
Subtle one. Spot it before scrolling 👇
.
.
.
The bug: Infinite loop risk. When
arr[mid] < target, the code sets left = mid instead of left = mid + 1. If mid ends up equal to left again on the next iteration (which happens when the search space shrinks to 2 elements), the loop never makes progress.Fixed version:
python
def binary_search(arr, target):
left, right = 0, len(arr)
while left < right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid
return -1
This is exactly why binary search is famously easy to get "almost right" but subtly wrong. Off-by-one errors here are so common that some engineers recommend writing out the invariant explicitly ("left is always a possible answer, right is always excluded") before coding it.
Do you write binary search from memory, or always double-check the boundaries? 👇
💰 SALARY NEGOTIATION #3 - Comparing Multiple Offers
Having multiple offers is the single strongest negotiation position you can be in - but a surprising number of people mishandle it by staying quiet about it.
✅ The script, once you have a competing offer:
"I wanted to be transparent with you - I've received another offer at $X with [notable perk, e.g., more equity / remote flexibility]. I'm genuinely more excited about this role because of [specific, real reason - team, mission, growth path]. Is there room to close the gap?"
Why this works:
✅ Transparency builds trust rather than looking like a bluff
✅ Naming a specific, genuine reason you prefer them makes it clear you're not just auctioning yourself off
✅ Companies would rather match a number than lose a candidate they already invested interview time in
⚠️ Never fabricate a competing offer. Recruiters talk to each other more than you'd think, especially in tight-knit industries, and getting caught destroys your credibility permanently.
If you don't have a competing offer, you can still negotiate - just anchor on market research (levels.fyi, Glassdoor, Blind) instead of a competing number.
Ever used a competing offer to negotiate? Did it work? 👇
Having multiple offers is the single strongest negotiation position you can be in - but a surprising number of people mishandle it by staying quiet about it.
✅ The script, once you have a competing offer:
"I wanted to be transparent with you - I've received another offer at $X with [notable perk, e.g., more equity / remote flexibility]. I'm genuinely more excited about this role because of [specific, real reason - team, mission, growth path]. Is there room to close the gap?"
Why this works:
✅ Transparency builds trust rather than looking like a bluff
✅ Naming a specific, genuine reason you prefer them makes it clear you're not just auctioning yourself off
✅ Companies would rather match a number than lose a candidate they already invested interview time in
⚠️ Never fabricate a competing offer. Recruiters talk to each other more than you'd think, especially in tight-knit industries, and getting caught destroys your credibility permanently.
If you don't have a competing offer, you can still negotiate - just anchor on market research (levels.fyi, Glassdoor, Blind) instead of a competing number.
Ever used a competing offer to negotiate? Did it work? 👇
🎯 CODING CHALLENGE #5 - Longest Substring Without Repeating Characters
Difficulty: Medium | Asked at: Amazon, Meta, Bloomberg
💡 Hint: This screams sliding window. Keep expanding a window to the right, and when you hit a repeat, shrink from the left until the repeat is gone.
Solution:
Complexity: O(n) time - each character is visited by
Common mistake: Resetting
Sliding window is one of the highest-ROI patterns to master - it solves a huge chunk of "substring" and "subarray" problems. Comfortable with it, or still building intuition? 👇
Difficulty: Medium | Asked at: Amazon, Meta, Bloomberg
Input: "abcabcbb"
Output: 3 ("abc")
Input: "bbbbb"
Output: 1 ("b")
💡 Hint: This screams sliding window. Keep expanding a window to the right, and when you hit a repeat, shrink from the left until the repeat is gone.
Solution:
python
def length_of_longest_substring(s):
seen = {}
left = 0
max_len = 0
for right, char in enumerate(s):
if char in seen and seen[char] >= left:
left = seen[char] + 1
seen[char] = right
max_len = max(max_len, right - left + 1)
return max_len
Complexity: O(n) time - each character is visited by
right once, and left only ever moves forward. O(min(n, alphabet size)) space for the hash map.Common mistake: Resetting
left to seen[char] + 1 even when the previous occurrence of char is OUTSIDE the current window (i.e., seen[char] < left). Without the seen[char] >= left check, you can accidentally move left backwards, which breaks the algorithm.Sliding window is one of the highest-ROI patterns to master - it solves a huge chunk of "substring" and "subarray" problems. Comfortable with it, or still building intuition? 👇
📄 RESUME ROAST #3
> "Team player with excellent communication skills, hard worker, fast learner, detail-oriented, passionate about technology."
Before I roast this - what's actually wrong with it? 👇
.
.
.
The roast:
Every single word here is an unverifiable adjective. "Team player" and "hard worker" mean nothing to a hiring manager because literally every resume claims them, and there's zero evidence attached.
This section is functionally invisible - recruiters' eyes skip right past it, and it takes up valuable space that could hold something specific.
✅ The fix: show, don't tell. Instead of claiming "excellent communication skills," demonstrate it:
> "Presented quarterly architecture reviews to both engineering and non-technical stakeholders, translating complex system tradeoffs into business impact."
That single sentence proves communication skills far more convincingly than the adjective ever could - and it does it without ever using the word "communication."
Go check your resume right now. Do you have any pure adjective-lists like this? Be honest 😅
> "Team player with excellent communication skills, hard worker, fast learner, detail-oriented, passionate about technology."
Before I roast this - what's actually wrong with it? 👇
.
.
.
The roast:
Every single word here is an unverifiable adjective. "Team player" and "hard worker" mean nothing to a hiring manager because literally every resume claims them, and there's zero evidence attached.
This section is functionally invisible - recruiters' eyes skip right past it, and it takes up valuable space that could hold something specific.
✅ The fix: show, don't tell. Instead of claiming "excellent communication skills," demonstrate it:
> "Presented quarterly architecture reviews to both engineering and non-technical stakeholders, translating complex system tradeoffs into business impact."
That single sentence proves communication skills far more convincingly than the adjective ever could - and it does it without ever using the word "communication."
Go check your resume right now. Do you have any pure adjective-lists like this? Be honest 😅
❤2