<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Software Engineering Review By Devrim on Medium]]></title>
        <description><![CDATA[Stories by Software Engineering Review By Devrim on Medium]]></description>
        <link>https://medium.com/@webdeveloper45?source=rss-94ba01839fc2------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*PJGKwFVQFGMn4RG2F70-ng.jpeg</url>
            <title>Stories by Software Engineering Review By Devrim on Medium</title>
            <link>https://medium.com/@webdeveloper45?source=rss-94ba01839fc2------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 13 Nov 2026 21:44:47 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@webdeveloper45/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Our Best Engineer Quit Over a $12K Raise. His Replacement Cost Us $280K.]]></title>
            <link>https://medium.com/javarevisited/our-best-engineer-quit-over-a-12k-raise-his-replacement-cost-us-280k-a50c933396a9?source=rss-94ba01839fc2------2</link>
            <guid isPermaLink="false">https://medium.com/p/a50c933396a9</guid>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Software Engineering Review By Devrim]]></dc:creator>
            <pubDate>Fri, 13 Nov 2026 16:45:03 GMT</pubDate>
            <atom:updated>2026-11-13T16:45:03.530Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RDTYQEsecahTTdd1HAn6Yw.png" /></figure><h4><em>Finance saved $12,000 by refusing a salary adjustment. Six months later, the same company was paying three people to do one engineer’s job.</em></h4><p>The argument started over $12,000. That’s what separated Daniel’s salary from the number he wanted, and apparently it was enough money to threaten the financial stability of a company that had just spent $180,000 redesigning its office. Our CFO, Richard, had personally approved the new furniture. He drew the line at paying the engineer who kept our payment infrastructure running.</p><p>Daniel had been with us for five years. He knew the billing platform well enough to identify production problems from a handful of log lines, and he’d helped us survive two acquisitions without losing a single major customer. His salary was $168,000, which wasn’t terrible until you considered the responsibilities we’d gradually dumped on him.</p><p>He asked for $180,000.</p><p>Richard rejected the request in eleven minutes.</p><p>The official explanation was compensation discipline. The unofficial explanation was that Daniel had never threatened to leave, and management had mistaken his patience for a lack of alternatives.</p><h3>The Engineer Who Made Everyone Else Look Productive</h3><p>Daniel wasn’t the loudest engineer in the company. He didn’t deliver inspirational speeches about engineering excellence, and his LinkedIn profile hadn’t been updated since the previous acquisition. He wrote Java, complained about Hibernate, and had a habit of asking uncomfortable questions whenever somebody proposed a database migration on Friday afternoon.</p><p>Our engineering team had fourteen developers, and Daniel was the person most of them contacted when something behaved strangely in production. He knew which RabbitMQ consumers were sensitive to message ordering, why one PostgreSQL table still had an unusual composite index, and which payment-provider timeouts couldn’t safely be treated as failed transactions.</p><p>Much of that knowledge existed in documentation, although the documentation rarely explained why a particular decision had been made. Daniel filled in those gaps during code reviews, incident investigations, and the occasional argument with Product. His GitHub contribution graph looked ordinary because explaining why somebody shouldn’t merge a dangerous change doesn’t generate much activity. During his performance review, our VP of Engineering, Kevin, praised Daniel’s reliability and technical judgment. Then he rated him as meeting expectations because Daniel hadn’t demonstrated enough visible leadership.</p><p>Daniel asked what visible leadership meant. Kevin mentioned presentations, cross-functional initiatives, and greater participation in engineering strategy.</p><p>Daniel reminded him that he’d led the recovery of a billing incident affecting forty enterprise customers three months earlier. Kevin agreed that the work had been valuable but said the promotion committee wanted broader organizational impact. Daniel asked whether he should have invited the committee to the incident.</p><p>Kevin didn’t laugh.</p><h3>The Raise Wasn’t Really About Money</h3><p>Daniel had received an offer from another company. The position paid $205,000, involved fewer operational responsibilities, and included a team of engineers who would share ownership of the platform.</p><p>He hadn’t accepted it yet.</p><p>He liked his colleagues, understood the business, and didn’t particularly want to spend six months learning another company’s collection of regrettable architectural decisions. He asked for a $12,000 adjustment because he believed it was a reasonable compromise.</p><p>Kevin supported the request.</p><p>Richard didn’t.</p><p>The CFO explained that granting an exception could encourage other employees to negotiate aggressively. He also pointed out that the company had established compensation bands and couldn’t allow individual engineers to dictate policy. Daniel asked whether those bands accounted for his responsibilities. Richard said compensation decisions considered many factors.</p><p>Daniel asked which factors justified paying him less than newly hired engineers with narrower responsibilities. Richard said discussing other employees’ salaries was inappropriate. Daniel thanked him for the meeting. Two weeks later, he resigned.</p><p>He didn’t threaten anyone, demand a counteroffer, or give an emotional farewell speech. He provided four weeks’ notice, prepared a handover document, and helped his colleagues identify the systems that needed new owners. Richard told Kevin that losing employees was an unavoidable part of running a business. He was technically correct, which was about the only satisfying thing anyone could say about his contribution.</p><h3>The Replacement Search Was a Comedy Written by Finance</h3><p>Recruiting started immediately.</p><p>The first candidate wanted $220,000. Richard rejected him before the technical interview because the salary exceeded the approved band.</p><p>The second candidate passed the coding assessment but struggled to explain how he’d prevent duplicate payment processing when a RabbitMQ message was redelivered after a consumer crash. Kevin liked his communication skills. The backend team was less enthusiastic about giving him responsibility for financial transactions. The third candidate was excellent. She understood transaction isolation, could reason about partial failures, and asked detailed questions about the team’s on-call rotation. When Kevin explained that the role involved supporting several legacy services, she requested $235,000.</p><p>Richard rejected her too. By the sixth week, the company had spent thousands on recruitment and conducted fourteen interviews without making an offer. Kevin asked Finance to reconsider the salary band. Richard suggested that the engineering team was being too selective.</p><p>Kevin replied that the company processed customer payments and that selecting engineers based on their willingness to accept a low salary was an interesting way to discover new financial risks.</p><p>Richard recommended expanding the search internationally. Kevin asked whether the company intended to pay international candidates according to their experience or simply hoped geography would make the problem disappear.</p><p>The meeting ended without a decision.</p><h3>The First Problem Wasn’t a Production Outage</h3><p>Three weeks after Daniel left, our product team requested a change to the billing reconciliation process. The feature itself wasn’t especially complicated. Enterprise customers wanted additional settlement details in their monthly reports, and the engineering team estimated roughly two weeks of implementation work.</p><p>The problem was that nobody understood one of the existing aggregation rules. Daniel had implemented it years earlier to handle settlement adjustments that arrived after the original reporting period. The code was documented, but the business reasoning depended on an old contract amendment that had never been linked to the repository.</p><p>Our new technical lead, Sarah, spent four days reconstructing the behavior from historical transactions. She eventually found the contract in an archived customer folder. The implementation was correct.</p><p>The documentation was incomplete.</p><p>The feature slipped by three weeks. Nothing exploded. No customers lost money, and there wasn’t a dramatic incident that could be blamed on a single bad decision. The company simply discovered that work Daniel had once handled routinely now required several engineers to investigate before anyone felt comfortable making a change.</p><p>That was considerably harder to explain in an executive presentation.</p><h3>The Contractor Cost More Than the Engineer</h3><p>By the third month, Kevin hired an external consultant to help with the billing platform.</p><p>The contractor charged $175 an hour and had strong experience with Java, PostgreSQL, and distributed payment systems. He was competent, professional, and appropriately skeptical of the company’s documentation. His first week was spent learning the architecture. His second was spent discovering which parts of the documentation were outdated. During the third, he asked why the team had several overlapping mechanisms for payment retry and reconciliation. Sarah explained the historical reasons as best she could.</p><p>The consultant suggested contacting the engineer who had designed them. Kevin told him Daniel no longer worked there. The consultant asked whether anyone had considered retaining him.</p><p>Kevin said Finance hadn’t approved the salary adjustment.</p><p>The consultant looked at his own invoice. He didn’t comment. Over the following months, the company paid for contractor hours, recruitment fees, and overtime from engineers covering Daniel’s former responsibilities. Some of that spending would have occurred regardless of his departure, but the additional cost of replacing his capacity was becoming impossible to ignore.</p><p>Richard requested a breakdown.</p><p>Sarah sent him one. He asked whether the numbers could be presented without including recruitment expenses. Sarah asked whether removing the expenses from the presentation would also remove them from the bank account.</p><h3>The New Hire Wasn’t the Problem</h3><p>Eventually, the company hired a Senior Backend Engineer named Michael for $218,000.</p><p>Michael was good. He had eight years of experience, understood distributed systems, and quickly earned the team’s respect. He also had the good sense to avoid pretending he understood five years of business decisions after reading a few architecture documents. During his second week, he discovered that several payment workflows depended on customer-specific rules that weren’t represented clearly in the service boundaries.</p><p>He proposed consolidating the logic.</p><p>Sarah explained that a previous consolidation attempt had failed because different customers had negotiated different settlement behavior.</p><p>Michael asked who understood those contracts. Sarah said they were still rebuilding that knowledge. Michael looked at the backlog and estimated that he would need several months to become comfortable owning the entire platform.</p><p>Kevin asked whether he could accelerate the process.</p><p>Michael said he could work faster, but he couldn’t manufacture historical context. He’d been hired to solve engineering problems, and understanding the problem was generally a useful part of that arrangement.</p><p>Kevin accepted the answer. Richard complained that the new hire wasn’t delivering enough value yet. Kevin reminded him that experienced engineers still required onboarding. Richard said that wasn’t what he’d expected for $218,000. Kevin asked whether he’d expected the salary to include time travel.</p><h3>Finance Finally Did the Math</h3><p>Six months after Daniel resigned, Kevin presented a financial review. The company had spent approximately $280,000 on replacement-related costs, including the new hire’s compensation commitments, contractor support, recruitment fees, and temporary staffing expenses. That figure wasn’t a clean measure of additional loss, since some salary costs would have existed even if Daniel had stayed. Kevin separated the incremental expenses from ordinary compensation to avoid turning the analysis into another executive fairy tale.</p><p>The conclusion was still ugly.</p><p>The company had refused a $12,000 adjustment and subsequently paid substantially more to restore the engineering capacity it had lost. Several projects had also been delayed, although Kevin deliberately avoided assigning speculative dollar values to every missed deadline.</p><p>Richard argued that Daniel might have left eventually anyway. Kevin agreed. He pointed out that uncertainty didn’t make the original decision intelligent.</p><p>The CEO, Martin, asked whether Daniel had been underpaid. Kevin said the external market had offered him significantly more money, and the company had failed to account for the scope of his responsibilities. He also acknowledged that management had allowed too much operational knowledge to accumulate around one engineer.</p><p>That second point mattered.</p><p>Daniel had been valuable, but the organization had become dangerously dependent on him. Paying him more would have improved retention prospects without solving the underlying concentration of knowledge. Martin asked why nobody had raised that concern earlier. Sarah opened the staffing review she’d submitted eight months before Daniel resigned. The risk was listed on page four. Martin read it.</p><p>Richard looked at the ceiling.</p><h3>Daniel Didn’t Come Back</h3><p>Martin authorized Kevin to contact Daniel.</p><p>The company was prepared to offer $230,000, a Staff Engineer title, and additional engineering support. Kevin called him on a Thursday afternoon and explained the proposal without pretending the previous negotiations had been handled well. Daniel listened politely. He said he appreciated the offer but wasn’t interested.</p><p>His new company had given him ownership of a smaller platform with clearer responsibilities. He had time to mentor engineers, participate in architectural decisions, and finish his work without spending every evening investigating somebody else’s emergency. Kevin asked whether compensation was the deciding factor.</p><p>Daniel said money had been the reason he started looking.</p><p>It wasn’t the reason he stayed away. He explained that he’d spent years accepting additional responsibilities while management treated his reliability as evidence that everything was under control. The rejected raise had simply clarified how the company valued that arrangement.</p><p>Kevin didn’t argue.</p><p>He wished Daniel well and ended the call.</p><h3>The Next Engineer Asked for $15K</h3><p>The following quarter, Sarah requested a $15,000 salary adjustment for another experienced engineer. Richard initially questioned the amount. This time, Kevin arrived with market compensation data, a documented assessment of the engineer’s responsibilities, and a plan to distribute critical system knowledge across the team.</p><p>The raise was approved.</p><p>Sarah also introduced scheduled knowledge-sharing sessions, explicit ownership for critical workflows, and protected time for documentation. Michael helped redesign the onboarding process so new engineers could learn the billing platform without depending on one person to explain every unusual behavior. The changes weren’t exciting. Nobody announced an engineering revolution.</p><p>Six months later, Michael could take a vacation without carrying his laptop to dinner, and the team had enough shared context to investigate most incidents without calling former employees.</p><p>During the annual budget review, Richard asked whether the company could reduce engineering compensation growth. Kevin said they could discuss it. He also suggested including the cost of replacing experienced employees in the calculation. Richard opened a new spreadsheet. For once, nobody objected.</p><h3>Build a Career Around Skills Companies Struggle to Replace</h3><p>The engineers who command strong compensation usually understand more than frameworks and coding syntax. They can reason about distributed systems, diagnose production failures, evaluate architectural trade-offs, and explain the business consequences of technical decisions.</p><p>I’m building an interactive AI-powered system design interview platform through <strong>ProdRescue AI</strong> for engineers preparing for Senior and Staff-level interviews. If you want to influence its development and request private beta access, complete the short research form:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fblue-sea-697d.quartiers047.workers.dev%3A443%2Fhttps%2Fdocs.google.com%2Fforms%2Fd%2Fe%2F1FAIpQLScLD53xFU73sirxXmKFfL9-M7FGL_5mM6a8_B0qQdaYce2atA%2Fviewform%3Fembedded%3Dtrue&amp;display_name=Google+Docs&amp;url=https%3A%2F%2Fblue-sea-697d.quartiers047.workers.dev%3A443%2Fhttps%2Fdocs.google.com%2Fforms%2Fd%2Fe%2F1FAIpQLScLD53xFU73sirxXmKFfL9-M7FGL_5mM6a8_B0qQdaYce2atA%2Fviewform%3Fusp%3Dheader&amp;type=text%2Fhtml&amp;scroll=auto&amp;schema=google" width="760" height="675" frameborder="0" scrolling="no"><a href="https://medium.com/media/0ff75ab6d435aa7f849ec31a69970e49/href">https://medium.com/media/0ff75ab6d435aa7f849ec31a69970e49/href</a></iframe><p>You can also get my free <strong>Senior Engineer Interview &amp; Production Playbook</strong>, covering practical backend engineering, production debugging, and system design:</p><p><a href="https://devrimozcay.gumroad.com/l/fdiown">Senior Engineer Interview Prep: Free 45-Minute System Design Framework + 5 Practical Guides</a></p><p>I publish deeper articles about production engineering, system design interviews, AI, and engineering careers on Substack. You can subscribe for free here:</p><p><a href="https://substack.com/@devrimozcay1">Devrim Ozcay | ProdRescue | Substack</a></p><p>senior software engineer salary, software engineer retention, engineering compensation, developer salary negotiation, tech employee turnover, senior engineer replacement cost, engineering leadership, software engineer career growth, Staff Engineer salary.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a50c933396a9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/javarevisited/our-best-engineer-quit-over-a-12k-raise-his-replacement-cost-us-280k-a50c933396a9">Our Best Engineer Quit Over a $12K Raise. His Replacement Cost Us $280K.</a> was originally published in <a href="https://medium.com/javarevisited">Javarevisited</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I Passed the Coding Interview. They Still Said I Wasn’t Senior Enough]]></title>
            <link>https://medium.com/javarevisited/i-passed-the-coding-interview-they-still-said-i-wasnt-senior-enough-7bda1d3992ce?source=rss-94ba01839fc2------2</link>
            <guid isPermaLink="false">https://medium.com/p/7bda1d3992ce</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-architecture]]></category>
            <dc:creator><![CDATA[Software Engineering Review By Devrim]]></dc:creator>
            <pubDate>Fri, 13 Nov 2026 16:40:36 GMT</pubDate>
            <atom:updated>2026-11-13T16:40:36.675Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zFThAygnbIsOpXzQwr8stA.png" /></figure><h4><em>Passing technical interviews is only part of getting a Senior Software Engineer offer. The harder part is proving you can own the decisions that matter.</em></h4><p>There’s a particular kind of rejection that stays with you longer than the others. You solve the coding problem, explain the time complexity, handle the edge cases, and leave the interview feeling like you’ve finally done everything right. A few days later, the recruiter tells you the team enjoyed speaking with you but didn’t see enough evidence of senior-level experience.</p><p>It’s difficult to know what to do with that feedback. You passed the technical exercise, and you’ve already spent years building production software. At work, people come to you when the database is slow, the deployment breaks, or a service starts behaving in ways nobody anticipated. Somehow, none of that was enough to convince a company that you could operate at the level you’re already working at.</p><p>The temptation is to respond by practicing another hundred coding problems. That’s understandable because coding problems have clear answers, measurable progress, and a satisfying sense of completion. Unfortunately, you can become significantly better at LeetCode without improving the part of your interview that caused the rejection. The missing evidence may have very little to do with your ability to write code.</p><h3>The Coding Round Proves Less Than You Think</h3><p>Imagine a candidate who solves a medium-difficulty algorithm problem in 25 minutes. The solution is correct, the complexity analysis makes sense, and the implementation handles the obvious edge cases. The interviewer has good evidence that this engineer can reason about algorithms and write code under pressure.</p><p>Now consider what that result doesn’t establish.</p><p>It doesn’t tell the interviewer whether the candidate can identify a dangerous production migration, recognize an unreliable retry strategy, or decide when a service should remain a monolith. It doesn’t show whether the engineer can take responsibility for an incident that involves several teams and incomplete information.</p><p>Those abilities require different evidence.</p><p>This distinction isn’t limited to one company’s hiring philosophy. Amazon’s published engineering interview guidance, for example, explicitly evaluates system design, technical competence, and behavioral evidence alongside coding. Its Senior-level preparation materials also emphasize the reasoning behind previous decisions and the candidate’s contribution to engineering outcomes. A candidate can perform well in one dimension and still leave important questions unanswered in another.</p><p>That doesn’t make the coding round pointless. It means passing it should change how you prepare for the remaining interviews.</p><h3>The Question That Exposes a Senior Engineer</h3><p>Consider a technical deep-dive question that sounds almost too simple.</p><p>“Tell me about a production incident you handled.”</p><p>A mid-level engineer might describe an incident where the application became slow, the team investigated the logs, and increasing the database connection pool helped restore performance.</p><p>That could be a perfectly reasonable account of what happened. But an interviewer trying to evaluate senior-level ownership may want to understand something deeper. Why was the connection pool exhausted? How did the engineer distinguish the symptom from the cause? What risks were introduced by increasing the pool size, and what changes prevented the same failure from returning?</p><p>Suppose the application used Spring Boot, HikariCP, and PostgreSQL. During a traffic spike, requests started waiting for database connections, and API latency increased dramatically. Increasing the maximum pool size might temporarily reduce waiting time. It could also make the situation worse if the database was already saturated with expensive queries, blocked transactions, or lock contention.</p><p>The correct decision depends on the evidence. I’d want to examine active versus idle connections, connection acquisition time, transaction duration, database wait events, and recent changes in query behavior. I’d also look for a correlation between the incident and a deployment, traffic pattern, or downstream dependency.</p><p>If a new endpoint introduced a query that held connections for several seconds, doubling the pool could simply allow more expensive queries to run concurrently. You might end up moving the bottleneck from the application pool to PostgreSQL itself. A strong interview answer explains how the engineer reached a conclusion and what they did to validate it.</p><p>The interviewer should leave understanding the investigation, the trade-offs, and the decisions the candidate personally owned.</p><h3>A Production Incident Is an Engineering Judgment Test</h3><p>Let’s take the database incident further.</p><p>Suppose the root cause is a new transaction that performs several external API calls before committing. Connections remain occupied while the application waits for a remote service.</p><p>The immediate fix might involve reducing traffic to the affected endpoint, disabling the new behavior behind a feature flag, or rolling back the deployment.</p><p>A longer-term solution would examine why network calls were placed inside a database transaction and whether the workflow could be restructured to shorten the transaction boundary.</p><p>Moving those calls outside the transaction can improve connection utilization, but it changes failure behavior. If the database commit succeeds and the external operation fails, the system may need an asynchronous recovery process or an explicit compensating action. That’s the kind of trade-off an experienced engineer should be comfortable discussing. Now imagine explaining this incident during a Senior interview.</p><p>You can describe the initial symptoms, the competing hypotheses, the evidence that eliminated them, the mitigation you selected, and the changes made afterward. If you have real metrics, include them. If you don’t remember exact figures, explain the direction and significance of the measurements without inventing numbers. A story like that gives the interviewer much more evidence than saying you improved database performance.</p><p>It shows how you behave when the answer isn’t obvious.</p><h3>Senior Engineers Are Expected to Own Consequences</h3><p>There’s another difference between implementing a technical solution and owning its consequences.</p><p>Suppose you’re asked to introduce asynchronous processing into an order service. The existing system handles orders synchronously, and customers occasionally experience long response times when downstream inventory or payment services are slow. A developer might suggest publishing order events to Kafka and processing them asynchronously.</p><p>That’s a plausible architectural direction.</p><p>But before changing the design, someone needs to establish what the API currently promises. Does a successful response mean the order was accepted, inventory was reserved, or payment was completed? If the response semantics change, existing clients may interpret a pending order as a confirmed purchase.</p><p>That can become a serious business problem. A Senior engineer should identify those contract implications before implementing the new workflow. They also need to consider idempotency, event ordering, reconciliation, and recovery from partial failures. If payment succeeds but inventory reservation fails, the system needs a defined outcome rather than an assumption that the next retry will somehow fix everything.</p><p>The architectural discussion becomes even more interesting when you introduce a migration constraint.</p><p>The existing system has thousands of active clients, several downstream consumers, and a release schedule that can’t accommodate a large coordinated deployment.</p><p>Now the engineer must explain how to evolve the system safely.</p><p>A credible plan might introduce explicit order states, maintain backward compatibility, deploy new consumers before switching producers, and migrate traffic incrementally. The exact sequence depends on the existing architecture, but the reasoning should account for failure recovery and observable business outcomes. This is what ownership looks like in a technical interview.</p><p>You’re responsible for what happens after the code is merged.</p><h3>Why Staff Interviews Feel Like a Different Profession</h3><p>The jump from Senior to Staff introduces another challenge. At Senior level, you may demonstrate ownership of a complex service or a significant technical project. Staff expectations often extend to influencing architecture across teams, aligning competing requirements, and guiding technical decisions that nobody can implement alone.</p><p>Consider an organization with six engineering teams using different approaches to event processing. One team relies on Kafka, another uses RabbitMQ, and several services communicate synchronously. The organization is experiencing inconsistent retry behavior, duplicated operational tooling, and expensive incident investigations.</p><p>A candidate might recommend standardizing everything on Kafka.</p><p>That recommendation is easy to make in an interview.</p><p>Actually delivering it would require understanding why the different systems exist, which guarantees their workloads require, and how much risk the migrations introduce.</p><p>Some services may need ordering within a particular business entity. Others may depend on delayed delivery, routing patterns, or operational characteristics that aren’t addressed simply by changing brokers. The right answer could involve shared engineering standards and improved observability without forcing every team onto the same infrastructure.</p><p>A Staff engineer should be able to explain how they would reach that decision with the teams involved. They need to establish technical direction while respecting the constraints of systems they don’t directly own.</p><p>This is why a Staff interview can feel uncomfortable even for someone with substantial production experience. The interviewer may be looking for evidence of influence and organizational judgment that doesn’t appear in a conventional system design diagram.</p><h3>Stop Using Years of Experience as Your Main Argument</h3><p>I’ve seen engineers describe themselves as Senior because they’ve spent seven or ten years writing software. Experience matters, but elapsed time doesn’t explain the scope of someone’s decisions. Two engineers can have the same number of years in the industry and very different responsibilities. One may have spent years implementing well-defined features inside a stable architecture. Another may have led complex migrations, handled critical production failures, and influenced technical decisions across multiple teams.</p><p>Neither career should be dismissed, but the evidence they can present in a Senior or Staff interview will differ.</p><p>Instead of leading with years of experience, identify the decisions you owned.</p><p>Think about the last time you disagreed with a proposed architecture. Explain what you noticed, how you evaluated the alternatives, and whether your recommendation changed the outcome. Consider a production incident where the obvious fix would have introduced another failure. Describe how you identified that risk and persuaded the team to choose a safer approach.</p><p>Look at a project where the requirements changed after implementation began. Explain how you managed the technical consequences without allowing the system to become impossible to maintain. These examples are more valuable than an impressive technology list because they reveal how you think.</p><p>They also help you identify whether your experience matches the expectations of the role you’re pursuing.</p><h3>A Better Way to Prepare for Your Next Interview</h3><p>If I were preparing for a Senior or Staff interview, I’d build an evidence file before spending another month studying random questions. I’d choose several real engineering situations from my career and reconstruct them in enough detail to defend the decisions.</p><p>One should involve a difficult production failure. Another should demonstrate a meaningful architecture trade-off. A third should show ownership of a project where the outcome depended on communication and coordination beyond writing code. For each example, I’d document the original constraints, the alternatives considered, the decision made, and the consequences.</p><p>Then I’d challenge the explanation as an interviewer would.</p><p>Why didn’t you choose the simpler solution? What would have happened if the database became unavailable? How did you know the migration was safe? Which metrics proved the change worked? What would you do differently if the same problem appeared again?</p><p>If I couldn’t answer one of those questions, I’d investigate the gap.</p><p>Sometimes the problem would be technical knowledge. Other times it would be a failure to remember or communicate the reasoning behind work I’d already done.</p><p>Both are fixable, but they require different preparation.</p><p>For system design practice, I’d apply the same principle. Rather than memorizing the architecture of another social media platform, I’d work through one design until I could explain its failure modes, capacity assumptions, and operational consequences.</p><p>A payment system is particularly useful for this because it forces careful reasoning about correctness. A notification platform is useful for understanding backpressure, retries, and third-party dependencies. A distributed scheduler introduces questions about leases, clock assumptions, worker failures, and duplicate execution.</p><p>The value comes from how deeply you can reason about each system, not from how many diagrams you’ve collected.</p><h3>Rejection Is Information, Even When the Feedback Is Terrible</h3><p>Some interview processes provide detailed technical feedback. Others send a generic rejection email that leaves the candidate guessing.</p><p>You shouldn’t treat every rejection as a perfectly accurate assessment of your ability. Interviewers can make mistakes, evaluation criteria vary, and hiring decisions involve factors candidates never see.</p><p>Still, repeated outcomes can reveal useful patterns.</p><p>If you consistently pass coding rounds but struggle in technical deep dives, investigate how you explain production decisions. If you perform well in system design but receive downleveling feedback, examine whether your examples demonstrate the ownership and influence expected at the target level.</p><p>If you’re reaching final rounds but failing behavioral interviews, look at how you communicate disagreements, failures, and technical leadership. The goal is to identify the smallest set of changes that could meaningfully improve your next performance.</p><p>You don’t need to convince yourself that every rejection was fair. You also don’t need to conclude that you’re incapable of reaching the level you want.</p><p>What matters is whether your preparation becomes more precise after each attempt.</p><h3>Your Next Interview Deserves Better Preparation Than Your Last One</h3><p>A rejection can make an experienced engineer question years of work, especially when the feedback is vague. But your previous engineering experience hasn’t disappeared because a company declined to make an offer.</p><p>The difficult part is learning how to present that experience in a format where someone unfamiliar with your work can evaluate it.</p><p>That means practicing the explanations you normally skip because they seem obvious. It means examining failure scenarios before an interviewer introduces them. It means becoming comfortable discussing decisions that had no perfect answer.</p><p>For Senior candidates, I’d focus on demonstrating technical ownership and production judgment.</p><p>For Staff candidates, I’d spend additional time on cross-team influence, architecture evolution, and the consequences of technical decisions across an organization.</p><p>Neither path requires pretending to know everything.</p><p>The engineers I respect most are comfortable explaining what they know, where their assumptions might fail, and how they would investigate uncertainty before making an expensive decision.</p><p>That’s a skill worth developing regardless of what happens in your next interview.</p><h3>Free Resources and Early Access</h3><p><strong>Read More on Substack</strong></p><p>I write about production engineering, distributed systems, system design interviews, and the technical decisions that separate experienced engineers from stronger Senior and Staff candidates. You can subscribe for free and follow the deeper engineering discussions here: <a href="https://substack.com/@devrimozcay1">https://substack.com/@devrimozcay1</a></p><p><strong>Download My Free Senior Engineer Interview Playbook</strong></p><p>I’ve put together five practical guides covering a 45-minute system design framework, production incident response, architecture decisions, and career positioning. The 27-page collection is free, with no payment required.</p><p><a href="https://devrimozcay.gumroad.com/l/fdiown">Senior Engineer Interview Prep: Free 45-Minute System Design Framework + 5 Practical Guides</a></p><p><strong>Help Build the System Design Interview Platform</strong></p><p>I’m researching why experienced engineers struggle with system design interviews, technical evaluations, and getting Senior or Staff offers. If you’ve been rejected, downleveled, or frustrated by the lack of useful interview feedback, I’d appreciate hearing about your experience. You can also request early access to the private beta.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fblue-sea-697d.quartiers047.workers.dev%3A443%2Fhttps%2Fdocs.google.com%2Fforms%2Fd%2Fe%2F1FAIpQLScLD53xFU73sirxXmKFfL9-M7FGL_5mM6a8_B0qQdaYce2atA%2Fviewform%3Fembedded%3Dtrue&amp;display_name=Google+Docs&amp;url=https%3A%2F%2Fblue-sea-697d.quartiers047.workers.dev%3A443%2Fhttps%2Fdocs.google.com%2Fforms%2Fd%2Fe%2F1FAIpQLScLD53xFU73sirxXmKFfL9-M7FGL_5mM6a8_B0qQdaYce2atA%2Fviewform%3Fusp%3Dheader&amp;type=text%2Fhtml&amp;scroll=auto&amp;schema=google" width="760" height="675" frameborder="0" scrolling="no"><a href="https://medium.com/media/0ff75ab6d435aa7f849ec31a69970e49/href">https://medium.com/media/0ff75ab6d435aa7f849ec31a69970e49/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7bda1d3992ce" width="1" height="1" alt=""><hr><p><a href="https://medium.com/javarevisited/i-passed-the-coding-interview-they-still-said-i-wasnt-senior-enough-7bda1d3992ce">I Passed the Coding Interview. They Still Said I Wasn’t Senior Enough</a> was originally published in <a href="https://medium.com/javarevisited">Javarevisited</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Your SaaS Has 20 Microservices. Nobody Knows Which One Will Fail First]]></title>
            <link>https://medium.com/engineering-playbook/your-saas-has-20-microservices-nobody-knows-which-one-will-fail-first-3712f7644064?source=rss-94ba01839fc2------2</link>
            <guid isPermaLink="false">https://medium.com/p/3712f7644064</guid>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[startup]]></category>
            <category><![CDATA[saas]]></category>
            <dc:creator><![CDATA[Software Engineering Review By Devrim]]></dc:creator>
            <pubDate>Thu, 12 Nov 2026 12:55:40 GMT</pubDate>
            <atom:updated>2026-11-12T12:56:25.903Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BCyJZh4vbL_Kt5cPy9MTRw.png" /></figure><h4><em>The most expensive backend failures often begin with architectural decisions that looked perfectly reasonable six months earlier.</em></h4><p>A SaaS company can have twenty microservices, a Kubernetes cluster, distributed tracing, automated deployments, and a dashboard full of green indicators while still having no reliable answer to a basic engineering question: what happens when the payment service times out after the database transaction succeeds?</p><p>Ask the backend team and you’ll probably hear about retries. Ask the infrastructure team and they’ll point to monitoring. Ask the CTO and they’ll explain that the architecture was designed for scale. Everyone has an answer, but those answers often describe individual components rather than the behavior of the entire system when something goes wrong.</p><p>That’s where production reliability becomes expensive. The system looks healthy because every service is reporting its own health. Meanwhile, a failed business operation can travel through several perfectly healthy services and leave behind inconsistent data that nobody discovers until a customer complains.</p><p>I’ve worked with Java and Spring Boot systems involving financial workflows, asynchronous messaging, database transactions, and distributed services. One lesson keeps coming back: the difficult part of backend engineering is rarely making a service work under normal conditions. It’s understanding what the rest of the system does when that service behaves in a way nobody planned for.</p><h3>The Architecture Diagram Is Usually More Confident Than the Engineers</h3><p>Imagine a SaaS platform that processes customer subscriptions. The architecture has separate services for billing, account management, notifications, and reporting. RabbitMQ handles asynchronous events, PostgreSQL stores transactional data, and Redis helps reduce repeated database reads.</p><p>On a diagram, the responsibilities are clean. Billing charges the customer, publishes an event, and the other services react accordingly. The entire design looks like something a senior engineer would confidently explain during a system design interview.</p><p>Now consider a slightly different sequence.</p><p>The billing service successfully commits a payment transaction. It publishes a message, but the connection to the broker fails before the application receives confirmation. The service cannot determine whether the message was accepted, so it retries.</p><p>The retry succeeds. Unfortunately, the first message was also accepted.</p><p>Two payment events are now moving through the system for one business operation.</p><p>The notification consumer might send two receipts. The reporting service might record duplicate revenue. An account-management consumer could activate the same subscription twice, depending on how its state transitions are implemented.</p><p>None of these services necessarily crashes. CPU usage remains normal, the database responds to queries, and the health checks continue returning HTTP 200.</p><p>The company has a business consistency problem that its infrastructure dashboard may never recognize.</p><p>This is why architecture reviews that focus entirely on service boundaries miss some of the most important production risks. You have to follow the business operation through the system, including what happens when individual steps are repeated, delayed, interrupted, or executed out of order.</p><h3>Your Retry Policy Might Be Creating the Incident</h3><p>Retries are one of those engineering decisions that sound responsible during a design review. A dependency fails, so the application tries again. Someone adds exponential backoff, configures a maximum attempt count, and considers the problem solved.</p><p>The missing question is whether the operation is safe to repeat.</p><p>Consider a Spring Boot consumer processing a payment event:</p><pre>@RabbitListener(queues = &quot;payment.completed&quot;)<br>public void handle(PaymentCompletedEvent event) {<br>    subscriptionService.activate(event.subscriptionId());<br>    notificationService.sendReceipt(event.customerId());<br>}</pre><p>The method is simple enough to pass a casual code review. It also leaves several important behaviors undefined.</p><p>What happens if subscription activation succeeds but receipt delivery fails? What happens when the consumer crashes before acknowledging the message? What if the broker redelivers the event while the first attempt is still processing? Does activating a subscription twice produce the same result as activating it once?</p><p>Depending on the listener’s acknowledgment configuration, transaction boundaries, and retry behavior, the consumer may execute the same business operation multiple times.</p><p>A safer design usually starts by defining a stable business operation identifier and enforcing the relevant uniqueness guarantees in durable storage.</p><pre>CREATE TABLE processed_payment_events (<br>    event_id UUID PRIMARY KEY,<br>    processed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()<br>);</pre><p>That table alone doesn’t make the workflow reliable. The duplicate check and the protected business-state change need to participate in an appropriate transaction, and external side effects require their own delivery strategy.</p><p>For example, if receipt delivery happens outside the database transaction, an outbox-backed notification workflow may be more appropriate than sending the email directly from the consumer.</p><p>The architecture has to account for partial success. Otherwise, adding retries can make the system more persistent at producing the wrong result.</p><h3>A Database Transaction Cannot Protect Your Entire Business Workflow</h3><p>One of the most common misunderstandings in distributed backend systems is treating a local database transaction as though it guarantees consistency across multiple services.</p><p>A Spring transaction can protect changes within its transactional resource. It cannot automatically roll back a message already consumed by another service, reverse an external payment, or undo an HTTP request sent to a third-party provider.</p><p>Suppose an order-processing workflow performs these operations:</p><ol><li>Reserve inventory in PostgreSQL.</li><li>Request payment authorization from an external provider.</li><li>Publish an order-confirmed event.</li><li>Notify the customer.</li></ol><p>The first operation is committed, the payment provider accepts the authorization, and the application crashes before the confirmation event is published.</p><p>What is the correct state of the order?</p><p>The answer depends on the business contract. The important point is that the engineering team must have an explicit answer before this failure occurs.</p><p>Sometimes the right solution involves an outbox pattern. Other workflows need compensating actions, reconciliation jobs, durable state machines, or carefully designed idempotency keys.</p><p>There is no architectural pattern that removes every trade-off. A reliable system makes those trade-offs visible and defines how the business recovers when execution stops halfway through.</p><h3>Twenty Services Can Mean Twenty Different Definitions of Success</h3><p>Microservices create another problem that rarely appears in architecture presentations: each team can define success differently.</p><p>The billing service considers a request successful when the payment provider confirms authorization. The account service considers it successful when subscription access is activated. The reporting service considers it complete when the financial event is recorded.</p><p>Those definitions are individually reasonable. They become dangerous when nobody has documented the conditions under which the entire business operation is considered complete.</p><p>A customer might be charged while their account remains inactive. A refund might succeed at the payment provider but fail to appear in the internal ledger. A canceled subscription might continue generating invoices because a downstream consumer never processed the cancellation event.</p><p>These are business failures expressed through software architecture.</p><p>If the team only monitors service availability, it may discover them much later than it should.</p><p>A useful reliability review therefore examines the lifecycle of a business operation. It identifies which service owns the authoritative state, which transitions are allowed, how failures are recorded, and how the system detects operations that become stuck between states.</p><p>For a payment workflow, that might mean measuring the number of authorized payments that have not reached their expected final state within an agreed time window.</p><p>That metric tells engineering leadership considerably more about business reliability than another dashboard showing that every container is running.</p><h3>The PostgreSQL Problem Nobody Notices Until Traffic Doubles</h3><p>Distributed systems receive plenty of attention, but an ordinary database transaction can quietly become the largest reliability risk in a SaaS backend.</p><p>Consider a service that loads an account, updates its balance, writes an audit record, calls another service, and commits the transaction.</p><p>During development, the external call takes 40 milliseconds. Nobody worries about it.</p><p>Months later, the dependency begins responding in 800 milliseconds during peak traffic. The transaction remains open while the application waits, potentially holding database locks and consuming a connection from the pool.</p><p>Other requests begin waiting for the same resources. Response times rise, connection-pool pressure increases, and application instances start accumulating pending requests.</p><p>Someone sees the symptoms and increases the HikariCP pool size.</p><p>That may temporarily change the queueing behavior, but it doesn’t resolve the transaction design. Under some workloads, additional connections can increase pressure on the database and make the situation worse.</p><p>A serious performance investigation needs to examine transaction duration, lock contention, query execution plans, connection-pool metrics, and the relationship between database work and external network calls.</p><p>The uncomfortable part is that the most important fix might involve changing application boundaries rather than adjusting infrastructure settings.</p><h3>Why Adding More Observability Doesn’t Automatically Solve This</h3><p>Observability is essential, but collecting more telemetry doesn’t guarantee that engineers know what to do with it.</p><p>I’ve seen how quickly technical discussions become centered on whether a team has enough dashboards, enough traces, or the right monitoring platform. Those tools matter, but they cannot replace a clear understanding of what the system is supposed to do.</p><p>If a message is processed twice and both attempts return successfully, ordinary error-rate monitoring may show nothing unusual.</p><p>If a financial workflow completes with inconsistent state, a trace might show every individual request returning a successful response.</p><p>The problem is that the system has no explicit signal for the violated business invariant.</p><p>Engineering teams should monitor technical behavior alongside the outcomes that matter to the business. For a subscription platform, that could include successful payment-to-activation completion, unresolved billing discrepancies, delayed event processing, or workflows stuck in intermediate states.</p><p>Those signals should have defined owners and operational responses. An alert that nobody understands or can act upon is simply another source of noise.</p><h3>What I’d Examine Before Approving a Growing SaaS Architecture</h3><p>When evaluating a production backend, I would begin with a small number of business-critical workflows rather than attempting to review every repository and infrastructure component at once.</p><p>For each workflow, I’d trace the entry point, data ownership, transaction boundaries, asynchronous messages, external dependencies, and expected final state. Then I’d examine the behavior under timeouts, duplicate delivery, partial commits, process termination, and dependency unavailability.</p><p>The most useful questions are often uncomfortable ones.</p><p>Can the same operation execute twice without corrupting business state? Is there a durable record of work that must be retried? Can the team identify a transaction that never completed? Does a database lock remain held during an external API call? Who is responsible for reconciling inconsistent records after an incident?</p><p>I’d also examine whether the existing safeguards have been tested. A retry policy documented in a design proposal tells me very little until I know how it behaves when the consumer crashes at the worst possible moment.</p><p>The outcome should be a prioritized engineering assessment. Some findings may require immediate attention because they threaten data integrity or financial correctness. Others may be manageable technical debt that can wait until the next architecture cycle.</p><p>A useful review makes that distinction explicit, so the team doesn’t waste its next quarter treating every architectural concern as equally urgent.</p><h3>The Most Expensive Architecture Decision Is Often the One Nobody Reopens</h3><p>Engineering teams rarely create unreliable systems because they lack intelligent people. More often, a design that was reasonable at an earlier stage survives long after the conditions that justified it have changed.</p><p>The company grows, traffic increases, new services appear, and business workflows become more complicated. Yet the assumptions behind the original transaction model, message-processing strategy, and data ownership boundaries remain largely untouched.</p><p>Eventually, every incident produces another local fix. A longer timeout here, an additional retry there, a scheduled reconciliation script somewhere else.</p><p>The system keeps running, but engineers become increasingly uncertain about the consequences of changing it.</p><p>That uncertainty has a cost. It slows delivery, increases the effort required to investigate incidents, and makes architectural decisions harder for engineering leadership to evaluate.</p><p>You don’t necessarily need to rebuild the platform. You need to understand which parts of it are carrying risks the organization can no longer afford to ignore.</p><p>And sometimes the best investment a CTO can make is having someone independently examine those assumptions before the next production incident forces the discussion.</p><h3>Backend Reliability &amp; Architecture Consulting for SaaS Teams</h3><p>I run <strong>ProdRescue AI</strong>, an independent engineering consulting practice focused on backend reliability, distributed systems, architecture reviews, and production engineering.</p><p>I work with SaaS founders, CTOs, and engineering leaders who need an experienced external perspective on critical backend workflows, recurring production incidents, database performance problems, and architectural decisions.</p><p>Engagements include focused architecture reviews, written technical risk assessments, prioritized recommendations, and ongoing advisory support. Monthly consulting plans start at <strong>$750</strong>, with additional options for engineering teams that need deeper involvement.</p><p><strong>Explore the consulting service:</strong><br><a href="https://devrimozcay.gumroad.com/l/uwzfw">https://devrimozcay.gumroad.com/l/uwzfw</a></p><p><strong>ProdRescue AI website:</strong><br><a href="https://www.prodrescueai.com/">https://www.prodrescueai.com/</a></p><p><strong>Business inquiries:</strong><br><a href="mailto:info@prodrescueai.com">info@prodrescueai.com</a></p><p>If your team is dealing with a specific production reliability or architecture problem, email me with a brief description of your system and the challenge you’re trying to solve. We can discuss whether a focused technical review or an ongoing advisory engagement would be appropriate.</p><h3>Frequently Asked Questions</h3><h3>How do you identify reliability risks in a microservices architecture?</h3><p>Start by tracing critical business operations across service boundaries, database transactions, message brokers, and external dependencies. Examine duplicate processing, partial failures, retry behavior, data consistency, and recovery mechanisms. Service health metrics alone are insufficient to establish end-to-end business reliability.</p><h3>What are the most common causes of recurring production incidents?</h3><p>Recurring incidents can arise from incomplete root-cause remediation, unsafe retries, transaction-boundary problems, resource contention, weak observability, and unresolved architectural dependencies. The exact causes must be established through system evidence rather than assumed from symptoms.</p><h3>How can Spring Boot applications prevent duplicate message processing?</h3><p>Use stable event identifiers, durable idempotency controls, appropriate database constraints, and transactionally consistent state changes. For workflows involving external side effects, patterns such as transactional outbox processing and reconciliation may also be necessary.</p><h3>When should a SaaS company conduct an architecture review?</h3><p>An independent architecture review can be useful before major migrations, significant traffic growth, critical product launches, or changes to financial and data-processing workflows. It can also help when recurring incidents or increasing development complexity suggest that existing architectural assumptions need to be reassessed.</p><h3>What is the difference between an architecture audit and ongoing engineering advisory?</h3><p>An architecture audit evaluates an agreed system or workflow within a fixed scope and produces findings and recommendations. Ongoing engineering advisory provides recurring technical review and decision support as the system and engineering priorities evolve.</p><p>microservices reliability, SaaS backend architecture, production engineering consulting, Spring Boot architecture review, distributed systems failures, PostgreSQL performance, backend reliability audit, microservices architecture problems.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3712f7644064" width="1" height="1" alt=""><hr><p><a href="https://medium.com/engineering-playbook/your-saas-has-20-microservices-nobody-knows-which-one-will-fail-first-3712f7644064">Your SaaS Has 20 Microservices. Nobody Knows Which One Will Fail First</a> was originally published in <a href="https://medium.com/engineering-playbook">Engineering Under Pressure</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I Got Rejected After 5 Senior Engineer Interviews. Then I Saw the Same Job Reposted]]></title>
            <link>https://medium.com/engineering-playbook/i-got-rejected-after-5-senior-engineer-interviews-then-i-saw-the-same-job-reposted-a931086f1259?source=rss-94ba01839fc2------2</link>
            <guid isPermaLink="false">https://medium.com/p/a931086f1259</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Software Engineering Review By Devrim]]></dc:creator>
            <pubDate>Wed, 11 Nov 2026 17:48:14 GMT</pubDate>
            <atom:updated>2026-11-11T17:48:28.566Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1LzrJoM1JFP4cuxujNc7HQ.png" /></figure><p>The job appeared on LinkedIn again at 8:17 on Monday morning. Same company, same Senior Backend Engineer title, same Java and Spring Boot requirements, and almost the same description I’d applied to six weeks earlier. The only noticeable change was the salary range, which had increased by $15,000.</p><p>I recognized it immediately because I’d spent twenty-three days interviewing for that position. I’d spoken with the recruiter, completed a Java coding exercise, survived two technical interviews, and met the Engineering Director. Five conversations, several hours of preparation, and a considerable amount of time rearranging my work schedule.</p><p>The company had rejected me nine days earlier. The recruiter said the team had decided to move forward with another candidate whose experience was a closer match. I thanked her, asked for feedback, and received the familiar promise that she’d share anything the team provided.</p><p>Now the position was open again.</p><p>I clicked the listing, read it twice, and sent the recruiter a message asking whether the hiring process had changed. I wasn’t expecting an answer, although I was curious enough to risk looking like someone who couldn’t accept rejection.</p><p>She replied twenty minutes later.</p><p>The company was still searching.</p><h3>The Interview Process Had Started Normally</h3><p>The company developed software for enterprise customers who needed to process large volumes of financial transactions. Its backend was built around Java, Spring Boot, PostgreSQL, and Kafka, with several older services that the engineering team wanted to modernize.</p><p>The recruiter had contacted me directly. She said my experience with payment processing and asynchronous workflows looked relevant, and she wanted to discuss a Senior Backend Engineer position on their transaction platform team.</p><p>I asked about the responsibilities before agreeing to an interview. She explained that the role involved owning backend services, improving reliability, reviewing architecture proposals, and helping other engineers with difficult production issues.</p><p>That sounded familiar.</p><p>I’d spent years working on Java services where database transactions, message redelivery, and external system failures created problems that weren’t particularly interesting until real money was involved. I had enough experience to understand the job, and the salary range was reasonable.</p><p>The recruiter said the company wanted to move quickly.</p><p>I’ve learned to be suspicious of that phrase. It usually means the company wants candidates to rearrange their schedules immediately while retaining the freedom to spend three weeks discussing whether the headcount still exists.</p><p>Still, the opportunity looked good.</p><p>I agreed to the first interview.</p><h3>The Technical Interviews Were Better Than Most</h3><p>The coding exercise involved implementing a small transaction-processing component. The interviewer wanted to see how I’d handle concurrent requests that attempted to modify the same account balance.</p><p>I used a database-backed approach and explained why correctness depended on the transaction boundaries and locking behavior. We discussed optimistic concurrency, isolation levels, and what would happen if two requests reached the service at nearly the same time.</p><p>The interviewer challenged a few assumptions, but the conversation was productive. I finished the exercise and received positive feedback the following day.</p><p>The next interview was with a Staff Engineer named Daniel.</p><p>He asked me to design a service that processed payment instructions from multiple upstream systems. Some requests arrived more than once, external providers occasionally timed out, and the platform needed to preserve a reliable history of each transaction.</p><p>We spent most of the hour discussing failure handling.</p><p>Daniel asked whether RabbitMQ could guarantee that a payment instruction would only be processed once. I explained that message delivery guarantees weren’t enough to establish business-level exactly-once processing and that the application needed durable idempotency controls.</p><p>He asked what I’d do if the external provider accepted a payment but the response was lost.</p><p>I described an uncertain state that required reconciliation rather than an automatic retry that might create another charge. We discussed how provider-side idempotency and status lookup capabilities would affect the design.</p><p>Daniel seemed satisfied.</p><p>At the end, he said the team had been struggling with similar problems in production. He asked whether I’d be comfortable working on systems where the architecture was already complicated and the documentation wasn’t always accurate.</p><p>I laughed and said that described most of the systems I’d inherited.</p><p>He laughed too.</p><p>The interview ended on a good note.</p><h3>The Fourth Interview Was Where Things Became Strange</h3><p>The fourth conversation was with another Senior Engineer named Michael. He’d been at the company for almost four years and was responsible for several services on the transaction platform.</p><p>He started by asking about my experience with Kafka.</p><p>I explained how I’d used messaging systems in production and discussed the differences between RabbitMQ and Kafka where they mattered. My recent work involved RabbitMQ more heavily, but I understood consumer groups, partitions, offsets, and the implications of replaying events.</p><p>Michael asked whether I’d ever managed a Kafka cluster.</p><p>I said I hadn’t been the primary owner of Kafka infrastructure. I’d worked with application-level producers and consumers, but cluster operations had generally belonged to a platform team.</p><p>He asked whether I’d configured broker replication and partition reassignment in production.</p><p>I said I understood the concepts but hadn’t personally operated those workflows.</p><p>He looked disappointed.</p><p>For the next twenty minutes, he asked questions about Kafka internals. We discussed partition leadership, consumer rebalancing, replication, and how broker failures could affect availability.</p><p>I answered some questions confidently and others less precisely.</p><p>Near the end, I asked how much of the role involved Kafka infrastructure management.</p><p>Michael said the team didn’t manage the clusters directly. A separate infrastructure group handled broker operations, but he believed senior backend engineers should understand the underlying platform deeply.</p><p>That was a reasonable expectation.</p><p>It was also different from the responsibilities the recruiter had described.</p><p>I left the call unsure whether I’d performed well enough.</p><p>Two days later, the recruiter invited me to the final interview.</p><h3>The Director Wanted Someone Who Could Lead Without Authority</h3><p>The Engineering Director, Sarah, joined the call from a conference room. She’d been with the company for less than a year and was responsible for modernizing several backend teams.</p><p>She asked about my previous projects and wanted to understand how I’d handled technical disagreements. I described a production incident where our team had discovered that long-running database transactions were exhausting the connection pool.</p><p>We discussed the investigation, the changes we’d proposed, and how we’d coordinated the deployment with other teams.</p><p>Sarah asked whether I’d led the effort.</p><p>I explained that I’d contributed to the investigation and implementation, while the technical lead had coordinated the broader work.</p><p>She asked whether I’d ever been responsible for technical direction across multiple teams.</p><p>I described several integrations where I’d coordinated API changes and deployment dependencies, but I was careful not to exaggerate the scope.</p><p>Sarah said the company needed someone who could influence architecture decisions across the transaction platform, even when the engineers involved didn’t report to them.</p><p>I asked whether that was a Staff Engineer responsibility.</p><p>She said the company expected strong Senior Engineers to demonstrate some of those capabilities.</p><p>We discussed the distinction for several minutes.</p><p>I explained that I was comfortable taking ownership of complex backend services and collaborating across teams, but I hadn’t independently led a large organization-wide architecture initiative.</p><p>Sarah thanked me for being clear.</p><p>The interview ended after forty-five minutes.</p><p>I received the rejection the following week.</p><h3>The Recruiter Said They’d Found Someone Better</h3><p>The email was polite and short. The company appreciated my time, enjoyed the conversations, and had decided to move forward with another candidate.</p><p>I asked whether the team could share feedback.</p><p>The recruiter said my technical performance had been strong, but the panel wanted someone with deeper Kafka experience and broader technical leadership.</p><p>I understood the feedback, although it seemed to describe a different position from the one I’d originally discussed.</p><p>I thanked her and moved on.</p><p>There wasn’t much else to do.</p><p>The company had evaluated my experience and decided it didn’t meet their requirements. That was disappointing, but hiring teams were entitled to make those decisions.</p><p>Nine days later, the job appeared on LinkedIn again.</p><h3>I Asked Why the Position Was Still Open</h3><p>When the recruiter replied to my message, she explained that the company hadn’t finalized a hire. The preferred candidate had accepted another offer, and the team was reopening the search.</p><p>That was understandable.</p><p>Candidates receive multiple offers, companies lose people during negotiations, and hiring processes don’t always end the way anyone expects.</p><p>I asked whether the team would reconsider candidates who’d already completed the interviews.</p><p>She said she’d check.</p><p>Later that afternoon, she called me.</p><p>The hiring manager was willing to revisit my application, she explained, but wanted to know whether I’d be interested in another conversation with the Engineering Director.</p><p>I asked what had changed since the previous interview.</p><p>She said the team had reviewed the market and realized that finding someone with deep Kafka infrastructure knowledge, strong Java backend experience, and broad architectural leadership was proving difficult.</p><p>I asked whether the role’s responsibilities had changed.</p><p>She said they hadn’t.</p><p>I asked whether the compensation range had changed.</p><p>She confirmed that it had increased.</p><p>Then I asked the question I’d been thinking about since Monday morning.</p><p>“If I didn’t meet the requirements nine days ago, what would make me qualified now?”</p><p>She was quiet for a moment.</p><p>Then she said the team was reassessing which skills were essential and which could be developed after hiring.</p><p>I appreciated the answer.</p><p>It was the first honest explanation I’d received about what was happening.</p><h3>The Second Conversation Was Uncomfortable</h3><p>Sarah joined the call two days later. She thanked me for being willing to speak again and acknowledged that the hiring process had been frustrating.</p><p>I asked whether the company was still looking for the same person.</p><p>She said the team had initially wanted someone who could take ownership of backend services while also providing broader technical direction. During the search, they’d realized that their expectations combined responsibilities that were usually distributed across different engineering roles.</p><p>I asked whether the Kafka infrastructure experience was still required.</p><p>She said it would be useful, but the platform team already managed the clusters. The Senior Backend Engineer would primarily work on application-level processing and reliability.</p><p>That sounded much closer to the original job description.</p><p>I asked why Michael had spent so much of our interview examining Kafka operations.</p><p>Sarah said he was concerned about the team’s dependence on infrastructure specialists and wanted backend engineers to understand the systems they used.</p><p>I could appreciate that concern.</p><p>But the company had treated a desirable capability as a reason to reject candidates for a role that didn’t require them to perform the work.</p><p>Sarah acknowledged that the interview panel hadn’t been fully aligned on the requirements.</p><p>She said they’d since clarified the evaluation criteria.</p><p>Then she asked whether I’d be interested in continuing.</p><h3>I Wanted the Job Less Than I Had Six Weeks Earlier</h3><p>The technology was still interesting. The compensation had improved, and the engineering problems sounded like work I’d enjoy.</p><p>But I’d spent nearly a month interviewing with a team that hadn’t agreed on what it wanted.</p><p>One interviewer evaluated Java and database correctness. Another focused on distributed payment processing. Michael tested Kafka infrastructure knowledge, while Sarah wanted evidence of broad technical leadership.</p><p>Each perspective was reasonable in isolation.</p><p>Together, they’d produced a hiring process where candidates were expected to satisfy several different interpretations of the same role.</p><p>I asked Sarah how technical decisions were made when senior engineers disagreed about architecture.</p><p>She explained that the team encouraged debate and generally relied on the Engineering Manager or Staff Engineer to make a final decision when consensus wasn’t possible.</p><p>I asked whether the team had experienced similar disagreements about the responsibilities of existing engineers.</p><p>She admitted that the organization was still adjusting after a restructuring.</p><p>That answer mattered more to me than the salary increase.</p><p>I could work in an imperfect organization. I’d done it before.</p><p>But I wanted to understand whether the confusion was limited to hiring or reflected how the team operated every day.</p><p>Sarah said the company was working on clearer ownership boundaries and engineering expectations.</p><p>I believed she was sincere.</p><p>I still wasn’t convinced the role was right for me.</p><h3>I Declined the Second Interview Process</h3><p>The recruiter called the following morning and asked whether I’d like to schedule another technical conversation.</p><p>I told her I appreciated the reconsideration but wouldn’t continue.</p><p>She sounded surprised.</p><p>She reminded me that the compensation range had increased and that the Engineering Director was personally interested in my candidacy.</p><p>I explained that my concern wasn’t primarily compensation. The interviews had revealed uncertainty about the responsibilities of the position, and I wasn’t comfortable committing to a role while those expectations were still being defined.</p><p>She asked whether I’d reconsider if the company made an offer without additional interviews.</p><p>I said I’d still need confidence that the role matched what I wanted.</p><p>We ended the conversation politely.</p><p>I didn’t feel particularly triumphant.</p><p>I’d spent six weeks pursuing a job, and I’d just declined an opportunity to return to the process.</p><p>But I also felt relieved.</p><h3>The Job Stayed Open for Another Month</h3><p>I noticed the listing again several weeks later. The company had changed the title from Senior Backend Engineer to Staff Backend Engineer.</p><p>The description now emphasized cross-team architecture, technical strategy, and leadership across multiple services. Kafka infrastructure experience remained listed as desirable rather than required.</p><p>I read the posting and laughed.</p><p>It was a much clearer description of what Sarah had been looking for during our final interview.</p><p>The company hadn’t necessarily made a bad decision by rejecting me. My experience didn’t fully match the responsibilities it ultimately wanted the person to own.</p><p>The problem was that those responsibilities hadn’t been clearly defined when the hiring process began.</p><p>I’d spent twenty-three days being evaluated for a position that was still taking shape.</p><p>The reposted job made that obvious.</p><h3>I Started Asking One Question Before Every Technical Interview</h3><p>After that experience, I began asking hiring managers what problem they expected the new engineer to solve during the first six months.</p><p>The answers were revealing.</p><p>One manager wanted someone to stabilize an unreliable backend service. Another needed an engineer who could take ownership of a large migration. A third was looking for someone to mentor a team that had grown quickly and lacked experienced technical guidance.</p><p>Those were concrete responsibilities.</p><p>They helped me understand what the company valued and whether my experience matched its needs.</p><p>I also asked whether the interview panel had agreed on the expectations for the role.</p><p>Most hiring managers said yes.</p><p>A few seemed surprised by the question.</p><p>One admitted that the team was still discussing whether the position should be senior or staff level.</p><p>I appreciated that honesty.</p><p>It saved both of us several weeks.</p><h3>The Rejection Wasn’t the Part That Bothered Me</h3><p>I’ve been rejected from jobs where the company made the right decision. Sometimes another candidate had more relevant experience, and sometimes I simply performed poorly.</p><p>That happens.</p><p>What frustrated me about this process was the uncertainty behind the evaluation.</p><p>The company had invited me to five interviews without establishing a shared understanding of the role. Each interviewer had assessed a different set of expectations, and the final decision reflected a combination of requirements that weren’t clearly connected to the original position.</p><p>When the preferred candidate withdrew, the company reconsidered those requirements.</p><p>That didn’t make the interviewers incompetent. It made the hiring process expensive for everyone involved.</p><p>The engineers had spent hours interviewing candidates. Recruiters had coordinated schedules and managed communication. Candidates had prepared, taken time away from work, and tried to demonstrate experience against a moving target.</p><p>I don’t know whether the company eventually hired someone.</p><p>I hope it did.</p><p>The engineering problems sounded difficult, and the team seemed to contain people who cared about solving them. But the next time I saw a Senior Engineer position advertised with requirements that sounded like three different jobs, I didn’t immediately start preparing for the technical interview. I asked the hiring manager what they actually needed someone to do. That conversation usually told me more than the job description.</p><h3>Preparing for Senior Backend Engineering Interviews</h3><p>If you’re preparing for Senior Java interviews, my <a href="https://devrimozcay.gumroad.com/l/epxiu">Senior Java &amp; Spring Boot Engineering OS</a> covers Java, Spring Boot, PostgreSQL, and the production problems that experienced backend engineers are expected to understand. The <a href="https://devrimozcay.gumroad.com/l/oordy">Senior &amp; Staff System Design Interview OS</a> focuses on architecture decisions, distributed systems, and the technical trade-offs that come up when interviewers challenge your design.</p><p>I’m also developing <a href="https://docs.google.com/forms/d/e/1FAIpQLScLD53xFU73sirxXmKFfL9-M7FGL_5mM6a8_B0qQdaYce2atA/viewform?usp=header">ProdRescue System Design Lab</a>, a private-beta platform for realistic system design interview practice and technical feedback. You can share your preparation challenges and request access through the form.</p><p>I write about <strong>production debugging and system design interviews</strong> on <a href="https://substack.com/@devrimozcay1">Substack</a>, including difficult hiring experiences, backend failures, and the engineering decisions that rarely appear in conventional interview guides.</p><p><em>Devrim Özçay — Founder, ProdRescue AI</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a931086f1259" width="1" height="1" alt=""><hr><p><a href="https://medium.com/engineering-playbook/i-got-rejected-after-5-senior-engineer-interviews-then-i-saw-the-same-job-reposted-a931086f1259">I Got Rejected After 5 Senior Engineer Interviews. Then I Saw the Same Job Reposted</a> was originally published in <a href="https://medium.com/engineering-playbook">Engineering Under Pressure</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I Spent 18 Hours on a Software Engineer Take-Home Assignment. They Used My Code Anyway]]></title>
            <link>https://medium.com/engineering-playbook/i-spent-18-hours-on-a-software-engineer-take-home-assignment-they-used-my-code-anyway-748621136fc9?source=rss-94ba01839fc2------2</link>
            <guid isPermaLink="false">https://medium.com/p/748621136fc9</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <dc:creator><![CDATA[Software Engineering Review By Devrim]]></dc:creator>
            <pubDate>Wed, 11 Nov 2026 16:34:50 GMT</pubDate>
            <atom:updated>2026-11-11T16:35:05.401Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vNZPp7lHBc4KYykBcK5YYA.png" /></figure><p>The rejection arrived on a Monday morning, eleven days after I’d submitted the assignment. The recruiter thanked me for the effort and explained that the engineering team had decided to move forward with someone whose experience was a closer match. There was no technical feedback, which was irritating considering I’d spent most of a weekend building something the company had described as a four-hour exercise.</p><p>I wasn’t particularly surprised by the rejection. I’d been looking for a Senior Backend Engineer position for almost two months, and I’d already learned that a pleasant interview didn’t guarantee anything. What bothered me was an email I received three weeks later from one of the engineers who’d reviewed my assignment.</p><p>He wanted to know why I’d chosen a particular approach to handling failed payment requests.</p><p>At first, I thought he was asking for feedback on the exercise. Then I noticed he’d included a screenshot of an internal pull request. The code looked familiar enough that I opened my old repository before replying.</p><p>The company appeared to be implementing part of the workflow I’d submitted.</p><h3>The Assignment Was Supposed to Be a Small Backend Exercise</h3><p>The company built billing software for subscription businesses. It had around sixty employees, a fairly polished website, and an engineering blog full of articles about reliability, distributed systems, and building software with care. The Senior Backend Engineer position involved Java, Spring Boot, PostgreSQL, and RabbitMQ.</p><p>The first interview was with an Engineering Manager named Kevin. We discussed my previous experience with payment processing, including how we’d handled message redelivery and uncertain outcomes from external providers. He seemed interested in the practical details, particularly the distinction between a failed HTTP request and a failed financial operation.</p><p>At the end of the call, he explained that the next stage involved a take-home assignment. He said the company preferred it to live coding because candidates could work in a familiar environment without someone watching them type.</p><p>I asked how much time they expected candidates to spend on it.</p><p>“About four hours,” he said. “We’re more interested in your decisions than how much code you write.”</p><p>That sounded reasonable. I had another interview scheduled later that week, but I could spare an evening.</p><p>The assignment arrived the following morning.</p><p>It described a service that accepted subscription payment requests, persisted them, and processed them asynchronously. The service needed to handle duplicate requests, transient provider failures, and situations where a payment provider might process a charge without returning a successful response.</p><p>There was also a requirement to expose payment status through an API.</p><p>I read the document twice.</p><p>The problem was almost identical to the one Kevin and I had discussed during our interview.</p><h3>Four Hours Became Eighteen</h3><p>I started on Friday evening. The basic Spring Boot application took less than an hour to set up, and the first endpoint was straightforward. I created a payment request model, added validation, and used PostgreSQL to persist the initial operation.</p><p>Then I reached the failure-handling requirements.</p><p>The assignment said a provider request could time out after the provider had accepted the payment. It also said duplicate charges were unacceptable, but it didn’t specify whether the simulated provider supported idempotency keys or a status lookup API.</p><p>Those details mattered.</p><p>If the provider supported idempotency keys, retries could be designed around a stable operation identifier. If it didn’t, blindly retrying after a timeout could charge the customer twice. A local database transaction wouldn’t solve that problem because PostgreSQL couldn’t roll back an operation performed by an external payment service.</p><p>I emailed the recruiter asking whether candidates should make assumptions about the provider’s capabilities.</p><p>She replied that I should document my assumptions and explain my decisions.</p><p>I decided to model uncertain outcomes explicitly. A payment could be pending, successful, failed, or awaiting reconciliation. I avoided automatically retrying an operation when the provider might already have accepted it.</p><p>That decision complicated the implementation.</p><p>I added a database uniqueness constraint to protect the logical payment operation, a worker that processed pending payments, and tests covering duplicate requests and concurrent execution. I also documented how the workflow would need to change depending on the provider’s guarantees.</p><p>By Saturday afternoon, I’d spent roughly nine hours on the project.</p><p>I could have stopped there. The application worked, the important failure cases were covered, and the README explained the trade-offs.</p><p>Instead, I started improving things.</p><p>I added structured error responses, integration tests with Testcontainers, and more detailed logging around payment transitions. I cleaned up the transaction boundaries and made sure the worker couldn’t hold a database connection while waiting unnecessarily for the simulated provider.</p><p>On Sunday morning, I found a race condition in one of my tests. Two concurrent requests could both attempt to create the same operation, and although the database constraint prevented duplicate records, the application returned an ugly exception for the losing request.</p><p>I fixed the behavior and added another test.</p><p>By the time I submitted the repository, I’d spent approximately eighteen hours on an assignment that was supposed to take four.</p><p>I knew that was excessive. But I’d worked on payment systems before, and I didn’t want to submit something that handled the happy path while quietly creating duplicate charges under failure.</p><p>The README was almost as detailed as the implementation.</p><p>I sent the link on Sunday evening.</p><h3>Their Feedback Was Surprisingly Specific</h3><p>Three days later, Kevin invited me to a technical review with two engineers. One was a Staff Engineer named Daniel, and the other was a Senior Backend Engineer named Chris.</p><p>They’d read the repository carefully. Daniel asked why I’d represented uncertain provider outcomes separately from ordinary failures. I explained that a timeout didn’t establish whether the provider had processed the payment and that retry behavior depended on guarantees outside our application.</p><p>Chris asked why I’d used PostgreSQL to coordinate processing instead of relying entirely on RabbitMQ.</p><p>I explained that the database represented the durable business state, while the broker could be used to trigger work. A message could be delivered more than once, and the consumer needed to tolerate that without creating another logical payment operation.</p><p>We discussed the implementation for nearly an hour.</p><p>Daniel suggested an alternative approach using a transactional outbox. I agreed that it would be useful if the service needed to guarantee publication of work after committing a database transaction. My implementation had simplified that part of the workflow because the assignment focused on payment processing rather than reliable event publication.</p><p>He seemed satisfied with the explanation.</p><p>Near the end, Chris asked whether I’d considered using a scheduled reconciliation process.</p><p>I said yes. The current implementation exposed uncertain outcomes and left room for reconciliation, but a real system would need a defined mechanism for resolving them, possibly through provider queries, settlement files, or operational review.</p><p>Kevin thanked me for the detailed submission.</p><p>He said the team would discuss the interview and get back to me.</p><p>I left the call feeling cautiously optimistic. They’d challenged the design, but the discussion had been productive. I’d expected a coding exercise and ended up having a fairly realistic architecture review.</p><p>The rejection arrived eleven days after I’d submitted the assignment.</p><p>The email didn’t mention the technical discussion.</p><h3>I Asked for Feedback and Got Silence</h3><p>I replied to the recruiter asking whether the engineering team could share anything specific about my submission. I’d invested enough time that I wanted to understand whether there had been a technical problem or simply a stronger candidate.</p><p>She said she’d check with the team.</p><p>A week passed.</p><p>I followed up once more, and she replied that the hiring process had been busy. She promised to send feedback when it became available.</p><p>I didn’t contact her again.</p><p>By then, I was interviewing with other companies and had more immediate problems to worry about. One wanted a live Java coding exercise, another had scheduled a system design round, and a third had disappeared after telling me the hiring manager was extremely interested in my background.</p><p>I archived the assignment repository and moved on.</p><p>Then Chris emailed me.</p><h3>The Screenshot Was What Made Me Angry</h3><p>Chris’s message was friendly. He said he’d enjoyed reviewing my assignment and had been thinking about the way I’d modeled uncertain payment outcomes. The team was working on a similar problem internally, and he wanted to know whether I’d encountered any issues with the approach in production.</p><p>He included a screenshot of a pull request discussion.</p><p>The screenshot showed a payment state model with an explicit uncertain outcome, along with a comment about avoiding retries until the provider’s result could be reconciled.</p><p>Those ideas weren’t unique to my assignment. They were established approaches to a well-known distributed systems problem, and I had no reason to believe I’d invented anything.</p><p>But the timing was uncomfortable.</p><p>The company had asked me to build a payment workflow, reviewed my implementation in detail, rejected me without feedback, and was now asking me to help evaluate a similar design in its production system.</p><p>I opened the original assignment document.</p><p>It described the task as an evaluation exercise. There was no explicit statement that the company intended to use candidate submissions in its product, and no agreement about compensation for additional design work.</p><p>I read Chris’s email again.</p><p>He wasn’t asking whether I wanted to join the team. He wanted free technical advice about a system the company was building.</p><p>I closed my laptop and went for a walk.</p><p>When I returned, I wrote a reply.</p><h3>I Asked Whether the Assignment Was Based on Their Actual Product</h3><p>I thanked Chris for the message and said I’d enjoyed the technical discussion. Then I asked whether the take-home assignment had been derived from a production problem the team was currently solving.</p><p>He replied the following afternoon.</p><p>He said the assignment was inspired by real engineering challenges at the company, although the exercise itself had been simplified for candidates. The team had been discussing payment reconciliation for some time, and my submission had prompted a few useful conversations.</p><p>I appreciated the explanation.</p><p>I also asked whether candidate submissions were routinely used as references for internal implementation work.</p><p>Chris said he wasn’t aware of a formal policy. He emphasized that the team hadn’t copied my repository and that the design concepts were common in payment systems.</p><p>I had no evidence that they’d copied my code, and I wasn’t going to accuse them of it. The screenshot didn’t prove anything beyond the fact that they were discussing similar architectural choices.</p><p>Still, I wasn’t comfortable providing additional unpaid consulting after completing an eighteen-hour assignment.</p><p>I told Chris I couldn’t review their internal design, but I’d be happy to discuss a paid consulting engagement if the company wanted detailed input on payment reliability.</p><p>He thanked me and said he’d pass the suggestion along.</p><p>I never heard from him again.</p><h3>The Problem Wasn’t That They Learned Something From My Interview</h3><p>Engineering interviews involve exchanging ideas. I’ve learned things from interviewers, and I’m sure interviewers have occasionally taken something useful from conversations with candidates.</p><p>There’s nothing inherently wrong with that.</p><p>If a candidate explains why an external payment timeout creates an uncertain outcome, the interviewer doesn’t need permission to remember the concept. The same applies to idempotency, database constraints, and other established engineering practices.</p><p>My frustration came from the amount of work the company had requested and the way it handled the process afterward.</p><p>The assignment was presented as a four-hour exercise. In practice, its requirements encouraged candidates to solve problems that could easily consume a full weekend. The company then conducted a detailed technical review, rejected me without meaningful feedback, and later contacted me about a related production design.</p><p>I had voluntarily spent eighteen hours on the implementation. Nobody forced me to add extra tests or refine the transaction boundaries.</p><p>That part was my decision.</p><p>But the experience made me reconsider what I was willing to do during an interview process.</p><h3>I Started Asking Better Questions Before Take-Home Assignments</h3><p>The next time a company mentioned a take-home exercise, I asked to see the scope before agreeing. I also asked whether the task was based on a current internal project and whether the company had a policy governing the use of candidate submissions.</p><p>One recruiter seemed surprised by the questions. Another said the company used a standardized exercise that had been reviewed specifically to avoid asking candidates to perform useful production work.</p><p>That second answer made me more comfortable.</p><p>I also started setting a time limit for myself. If an assignment was described as a four-hour exercise, I would spend approximately four hours on it and document what remained unfinished.</p><p>That required accepting something I hadn’t been comfortable with during the billing assignment.</p><p>I couldn’t demonstrate every production safeguard in a small exercise. I could implement the core requirements, identify the important failure modes, and explain how I’d extend the system if it were going into production.</p><p>A well-scoped assignment should give the interviewer enough material to evaluate those decisions.</p><p>If the company needed eighteen hours of implementation to determine whether I understood Spring Boot, PostgreSQL, and distributed systems, I wanted to know why.</p><h3>The Next Company Didn’t Ask Me to Write Any Code at Home</h3><p>A month later, I interviewed with a company that maintained a large backend platform for business customers. The first technical round involved discussing a production incident, and the second was a live design exercise with a Staff Engineer.</p><p>We spent seventy minutes working through a message-processing problem. The interviewer changed the requirements several times, asked me to explain the trade-offs, and challenged my assumptions about retries and database consistency.</p><p>At the end, he said the team had enough information to evaluate my approach.</p><p>There was no repository to submit.</p><p>No weekend disappeared into integration tests.</p><p>The company made an offer after the final interview, and I accepted.</p><p>I don’t think that proves live interviews are always better than take-home assignments. Some engineers perform poorly when someone watches them solve problems, and a carefully designed take-home exercise can reveal useful information about code quality and engineering judgment.</p><p>But the scope matters.</p><p>So does the company’s behavior after the candidate has completed the work.</p><h3>I Still Have the Repository</h3><p>The payment processing assignment is still in my private GitHub account. I occasionally open it when I want to revisit a particular implementation detail or test a change to the concurrency handling.</p><p>It’s a decent little Spring Boot project.</p><p>There are things I’d do differently now. I’d simplify parts of the domain model, improve the reconciliation interface, and remove a few abstractions that made sense at midnight on Saturday but look unnecessary in daylight.</p><p>I also wouldn’t spend eighteen hours building it for a company that had promised a four-hour evaluation.</p><p>The experience didn’t convince me that every take-home assignment is a scam. I don’t know whether the company used my code, and the screenshot Chris sent wasn’t evidence of copying. What I do know is that the assignment was closely related to work the company was doing and that an engineer later asked me for additional technical input after I’d been rejected.</p><p>That was enough to change how I approached future interviews.</p><p>A company can learn a great deal about a candidate in four hours.</p><p>If it needs an entire weekend of production-quality engineering work, it should be prepared to explain why.</p><h3>For Engineers Preparing for Backend Interviews</h3><p>If you’re preparing for Java and backend engineering interviews, my <a href="https://devrimozcay.gumroad.com/l/epxiu">Senior Java &amp; Spring Boot Engineering OS</a> covers Spring Boot, PostgreSQL, concurrency, and practical production problems. The <a href="https://devrimozcay.gumroad.com/l/oordy">Senior &amp; Staff System Design Interview OS</a> focuses on distributed systems, reliability, and the architectural decisions that often appear in advanced technical interviews.</p><p>I’m also building <a href="https://docs.google.com/forms/d/e/1FAIpQLScLD53xFU73sirxXmKFfL9-M7FGL_5mM6a8_B0qQdaYce2atA/viewform?usp=header">ProdRescue System Design Lab</a>, a private-beta platform for realistic system design interview practice and technical feedback. You can share your interview challenges and request access through the form.</p><p>I write about <strong>production debugging and system design interviews</strong> on <a href="https://substack.com/@devrimozcay1">Substack</a>, including difficult hiring experiences, backend engineering failures, and the technical decisions that rarely fit into standard interview exercises.</p><p><em>Devrim Özçay — Founder, ProdRescue AI</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=748621136fc9" width="1" height="1" alt=""><hr><p><a href="https://medium.com/engineering-playbook/i-spent-18-hours-on-a-software-engineer-take-home-assignment-they-used-my-code-anyway-748621136fc9">I Spent 18 Hours on a Software Engineer Take-Home Assignment. They Used My Code Anyway</a> was originally published in <a href="https://medium.com/engineering-playbook">Engineering Under Pressure</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I Passed the Coding Interview. Then They Offered Me a Junior Engineer Salary]]></title>
            <link>https://medium.com/engineering-playbook/i-passed-the-coding-interview-then-they-offered-me-a-junior-engineer-salary-e669863ae82b?source=rss-94ba01839fc2------2</link>
            <guid isPermaLink="false">https://medium.com/p/e669863ae82b</guid>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-architecture]]></category>
            <dc:creator><![CDATA[Software Engineering Review By Devrim]]></dc:creator>
            <pubDate>Wed, 11 Nov 2026 16:32:55 GMT</pubDate>
            <atom:updated>2026-11-11T16:33:14.971Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PgaKtVEZbqJ2llwS_kOdMg.png" /></figure><p>The recruiter called on a Wednesday afternoon, congratulated me on passing the final interview, and offered me $82,000. I asked her to repeat the number because we’d discussed a salary range of $125,000 to $145,000 before the first technical round. She repeated it, sounding considerably less enthusiastic the second time.</p><p>I had spent twenty-six days interviewing for a Senior Backend Engineer position. I’d completed a coding assessment, two technical interviews, and a conversation with the Engineering Director. Nobody had mentioned that the company was considering me for a different level.</p><p>The recruiter explained that the interview panel liked my experience but believed I would be a better fit as a Software Engineer II. The company still wanted to hire me, she said, and there would be opportunities for promotion once I’d demonstrated my capabilities internally.</p><p>I asked whether the job responsibilities had changed.</p><p>She said they hadn’t.</p><p>That was an interesting way to save forty-three thousand dollars.</p><h3>The Job Description Was Very Clear About What They Wanted</h3><p>The company built software for insurance providers. Its backend was mostly Java and Spring Boot, with PostgreSQL, RabbitMQ, and a collection of older services that had accumulated enough business logic to make everyone nervous about touching them.</p><p>The job posting asked for at least five years of backend experience, familiarity with distributed systems, and the ability to take ownership of production services. Engineers were expected to review architecture proposals, investigate incidents, and help less experienced developers make technical decisions.</p><p>I’d been doing that kind of work for years. My previous projects included payment processing, asynchronous collection workflows, and backend services where a small mistake could become an expensive accounting problem.</p><p>During the initial recruiter call, I asked about compensation because I didn’t want to spend another month interviewing for a role that couldn’t meet my expectations. She confirmed the advertised range and said my experience appeared consistent with the senior position.</p><p>I asked whether there was a separate leveling process.</p><p>She said the technical interviews would determine whether I met the team’s expectations. That seemed reasonable, although I should have asked what would happen if the panel decided I didn’t meet the senior bar.</p><p>I didn’t think much about it at the time. I had a job to find, and this one looked promising.</p><h3>The Coding Interview Wasn’t Particularly Difficult</h3><p>The first technical round involved implementing a small order-processing service in Java. The application received orders, validated inventory availability, and persisted state changes. The interviewer wanted to see how I structured the code and handled concurrent updates.</p><p>I used Spring Boot, kept the domain model fairly small, and explained why inventory changes needed to be protected at the database level. We discussed optimistic locking, transaction boundaries, and what should happen when two requests attempted to reserve the same item.</p><p>The interviewer asked whether I’d use Redis to coordinate reservations. I said I wouldn’t introduce it without a reason, especially when PostgreSQL could enforce the relevant consistency rules. He agreed that the simpler approach was appropriate for the stated workload.</p><p>The exercise lasted about seventy minutes. I finished the main implementation, added tests for conflicting reservations, and explained the limitations of the design. There were things I’d improve in a production application, but the interviewer seemed satisfied.</p><p>The recruiter emailed the following morning to say I’d passed.</p><p>The next round was system design.</p><h3>Their System Design Problem Looked Suspiciously Like Their Production Architecture</h3><p>The Staff Engineer introduced a service responsible for processing insurance claim events. Multiple external systems submitted updates, some events arrived out of order, and downstream applications needed a consistent view of claim status.</p><p>I started by asking how claims were identified and whether the external systems provided reliable event identifiers. We discussed duplicate delivery, ordering, and the business rules governing status transitions.</p><p>The interviewer explained that the existing implementation occasionally produced incorrect claim states when messages arrived in an unexpected sequence. The team had tried increasing consumer concurrency to improve throughput, but that had made some problems harder to reproduce.</p><p>I asked whether the system preserved the original events.</p><p>He said it did, although replaying them was difficult.</p><p>We spent the next hour discussing how to separate the incoming event history from the current business state, how to make updates idempotent, and what guarantees the database needed to enforce. I suggested keeping enough information to reconcile conflicting events without assuming that RabbitMQ could provide global ordering across independent producers.</p><p>The interviewer challenged several parts of the design. At one point, he asked whether I’d introduce Kafka to make replay easier. I said Kafka could help with event retention and replay, but changing brokers wouldn’t automatically resolve ambiguous business ordering or invalid state transitions.</p><p>He laughed and said that was a discussion they’d been having internally.</p><p>The interview ran fifteen minutes over schedule. Before leaving, he told me the team had been dealing with a similar problem for months and appreciated the conversation.</p><p>I felt good about it. I’d been asked to reason through a production problem rather than draw an architecture that looked impressive on a whiteboard.</p><p>The recruiter called two days later and scheduled the final interview.</p><h3>The Engineering Director Asked Me About Leadership</h3><p>The director’s name was Thomas. He’d joined the company eighteen months earlier and was responsible for three engineering teams. He asked about projects I’d owned, production incidents I’d handled, and how I’d worked with engineers who disagreed with my recommendations.</p><p>We spent a while discussing a Spring Boot service that had suffered connection pool exhaustion. I’d helped investigate the issue and found that certain transactions remained open while the application waited for an external HTTP service.</p><p>Thomas asked how I’d convinced the team to change the implementation.</p><p>I explained that we’d compared connection pool metrics with request traces and demonstrated that the long transaction duration was causing contention. The change required coordination because moving the external call outside the transaction affected failure handling and consistency guarantees.</p><p>He asked whether I’d made the final architectural decision.</p><p>I said the team had reviewed the proposal together and the technical lead had approved the change. I’d contributed to the investigation and implementation, but I wasn’t going to pretend I’d been the sole decision-maker.</p><p>Thomas asked how many engineers I’d mentored.</p><p>I explained that I’d regularly reviewed code and helped junior developers investigate production issues. I hadn’t formally managed anyone, and I didn’t have direct reports.</p><p>He asked whether I’d led a project involving multiple engineering teams.</p><p>I described a service integration where I’d coordinated API changes and deployment dependencies with another team. It wasn’t a company-wide initiative, and I said so.</p><p>Thomas seemed interested in the distinction. He asked a few more questions about ownership, then explained that the company wanted senior engineers to influence technical direction beyond their immediate services.</p><p>I said that was the kind of responsibility I wanted to grow into.</p><p>He thanked me for the conversation.</p><p>The following week, the recruiter called with the offer.</p><h3>I Asked for the Interview Feedback in Writing</h3><p>When the recruiter told me the company wanted to hire me as a Software Engineer II, I asked which expectations I’d failed to meet.</p><p>She said the panel believed I had strong backend fundamentals but needed more experience driving cross-team technical initiatives. Thomas had also wanted clearer evidence of mentoring and broader architectural leadership.</p><p>That feedback wasn’t entirely unreasonable. I’d been honest about my experience, and I hadn’t claimed to be a Staff Engineer responsible for technical direction across an organization.</p><p>What confused me was the relationship between the feedback and the position.</p><p>The job description emphasized owning backend services, handling production incidents, and reviewing technical decisions. I’d demonstrated those capabilities during the interviews. The company was now evaluating me against expectations that hadn’t been clearly described during the initial screening.</p><p>I asked whether the Software Engineer II role came with a narrower scope.</p><p>The recruiter said the responsibilities would largely be the same because the team needed someone experienced enough to work independently.</p><p>I asked whether the company had a documented promotion process.</p><p>She said promotions were reviewed twice a year and depended on performance, business needs, and manager recommendations.</p><p>I asked whether they could guarantee a promotion after six months if I performed the responsibilities of the senior position.</p><p>She said they couldn’t make that commitment.</p><p>I thanked her and asked for the complete offer in writing.</p><p>She sent it that evening.</p><p>The title was Software Engineer II. The base salary was $82,000. The offer mentioned eligibility for performance reviews but contained no written commitment to promotion or compensation adjustment.</p><p>I opened the original job posting.</p><p>It still advertised Senior Backend Engineer.</p><p>The salary range was still $125,000 to $145,000.</p><h3>I Spoke to Someone Who’d Worked There</h3><p>A former colleague knew an engineer who’d left the company earlier that year. I asked for an introduction because I wanted to understand whether the leveling decision was unusual.</p><p>The engineer agreed to a short call. He’d worked there for almost three years and had left for another backend position.</p><p>I explained the interview process and the offer.</p><p>He wasn’t particularly surprised.</p><p>He said the company had a fairly strict internal leveling structure, but the expectations weren’t always communicated clearly during recruitment. Some candidates entered at a lower level than the advertised role, especially when the hiring manager believed they needed more evidence of cross-team leadership.</p><p>I asked whether engineers could move up quickly.</p><p>He said it happened, but promotions were difficult to predict. The company had calibration meetings, budget constraints, and a tendency to expect people to demonstrate the next level’s responsibilities for a significant period before receiving the title.</p><p>He told me about a colleague who’d spent more than a year performing work associated with a senior role before being promoted.</p><p>I asked whether the company had treated him well otherwise.</p><p>He said the engineering teams were generally competent and the technical problems were interesting. He’d enjoyed working with several colleagues, although he eventually left because compensation had fallen behind the market.</p><p>That was useful information.</p><p>The company wasn’t necessarily trying to deceive me. It might genuinely have believed that my experience belonged at a lower internal level.</p><p>But I was being asked to accept senior-level operational responsibility at a salary significantly below the range we’d discussed.</p><p>I needed to decide whether that arrangement made sense for me.</p><h3>The Hiring Manager Called Me Personally</h3><p>Two days later, Thomas asked whether we could speak.</p><p>He said the team had enjoyed my interviews and wanted me to join. The Staff Engineer had specifically mentioned my understanding of message processing and database consistency, and the team believed I could contribute quickly.</p><p>I thanked him and asked about the leveling decision.</p><p>Thomas explained that their senior engineers were expected to lead technical initiatives across multiple teams. He believed I had the potential to reach that level but hadn’t demonstrated enough experience doing it independently.</p><p>I said I understood the distinction.</p><p>Then I asked why the company had advertised the role as Senior Backend Engineer when the actual responsibilities appeared to include significant independent ownership without a senior title.</p><p>He said the team was open to hiring at different levels depending on the candidate.</p><p>I asked whether that flexibility had been discussed before the interviews.</p><p>He acknowledged that it hadn’t been communicated clearly.</p><p>We talked about compensation. I explained that I’d entered the process based on the advertised range and that the offer represented a substantial reduction from the minimum we’d discussed.</p><p>Thomas said the company couldn’t pay $125,000 for a Software Engineer II position without creating internal compensation problems.</p><p>I understood his concern. Companies have salary bands, and hiring someone far above the range for a particular level can create legitimate issues.</p><p>But those internal constraints hadn’t appeared after my interviews. They’d existed before the recruiter contacted me.</p><p>I asked whether he could reconsider the level based on the responsibilities the team needed covered.</p><p>He said the interview panel’s decision was final.</p><p>I told him I’d need to decline.</p><p>Thomas sounded disappointed. He said he thought I could have a strong career at the company and that promotions were possible for engineers who demonstrated consistent performance.</p><p>I said I appreciated the offer, but I couldn’t accept a lower salary based on a promotion that might or might not happen.</p><p>We ended the call politely.</p><h3>The Recruiter Sent One More Email</h3><p>The following Monday, Rebecca emailed to ask whether I’d reconsider if the company increased the base salary to $90,000.</p><p>I read the message twice.</p><p>The additional eight thousand dollars didn’t change the level, the responsibilities, or the promotion process. It also remained well below the compensation range that had been confirmed before the interviews.</p><p>I replied that I appreciated the revised offer but would still decline.</p><p>She thanked me for my time and wished me well.</p><p>That was the end of the process.</p><p>Twenty-six days, four interviews, a system design discussion about their actual production problems, and an offer for a different position.</p><p>I added the company to my spreadsheet and marked the outcome as <em>declined</em>.</p><p>It felt strange. I’d spent months trying to get an offer, and I’d just rejected one.</p><h3>I Changed Two Questions in My Recruiter Screenings</h3><p>After that experience, I started asking recruiters whether the advertised level was fixed and whether the company might offer a lower title based on interview feedback.</p><p>Most recruiters answered directly. Some said the team was hiring across multiple levels and explained the corresponding salary ranges. Others confirmed that the role had a specific level and that candidates who didn’t meet the requirements would simply be rejected.</p><p>Both answers were useful.</p><p>I also asked whether the salary range applied to every level under consideration. One recruiter explained that the advertised range covered both mid-level and senior positions, with different internal bands. Another told me that compensation depended on interview performance, although she couldn’t explain how the company made those decisions.</p><p>I didn’t automatically reject companies that hired across levels. There are reasonable reasons to do it, particularly when a team has several openings or is flexible about the exact experience it needs.</p><p>I wanted to understand the possibilities before spending several weeks interviewing.</p><p>That simple change saved me time.</p><p>It also made the conversations less awkward. If a company was considering me for a mid-level position, we could discuss whether the responsibilities and compensation made sense before either side invested heavily in the process.</p><h3>I Eventually Took a Job With a Less Impressive Title</h3><p>A few weeks later, I interviewed with a company that called the position Backend Engineer. There was no Senior in the title, and the recruiter explained that the organization used relatively broad engineering levels.</p><p>The role involved owning Java services, improving production reliability, and working with other engineers on architecture changes. The compensation range was higher than the first company’s senior range, which made the title considerably less interesting to me.</p><p>I completed two technical interviews and met the Engineering Manager.</p><p>The manager explained how the team evaluated performance, what responsibilities I’d have initially, and how compensation reviews worked. The company didn’t promise rapid promotion, and I didn’t ask for one.</p><p>The offer matched the range we’d discussed.</p><p>I accepted.</p><p>During my first month, I spent several days investigating a PostgreSQL performance issue and helped another engineer untangle a particularly ugly Spring transaction problem. Nobody seemed concerned that my title lacked the word Senior.</p><p>The work was difficult enough.</p><h3>I Still Think About That $82,000 Offer</h3><p>I don’t believe every engineer with five years of experience deserves a senior title. Years of employment are a poor substitute for evidence of technical judgment, ownership, and the ability to work through difficult problems.</p><p>I also understand why companies maintain different engineering levels. A senior engineer at one organization may have responsibilities that resemble a mid-level position somewhere else. Titles are inconsistent, and compensation structures vary.</p><p>The issue with that interview process was simpler.</p><p>The company had advertised a particular position, confirmed a compensation range, and spent almost a month evaluating me. After deciding I didn’t meet its senior expectations, it offered a lower-level position while expecting me to perform much of the work described in the original posting.</p><p>That might have been acceptable to another candidate. Someone changing industries, returning after a career break, or prioritizing a particular company might reasonably decide the opportunity was worth it.</p><p>For me, it wasn’t.</p><p>The recruiter had described the lower level as an opportunity to prove myself. I understood the argument, but I was already being asked to take responsibility for production systems, make architectural decisions, and help the team solve problems it hadn’t managed to fix.</p><p>Those responsibilities were real.</p><p>The promotion was hypothetical.</p><p>I didn’t need another twenty-six days of interviews to understand the difference.</p><h3>For Engineers Navigating Senior-Level Interviews</h3><p>If you’re preparing for backend interviews where companies expect production judgment and architecture experience, my <a href="https://devrimozcay.gumroad.com/l/epxiu">Senior Java &amp; Spring Boot Engineering OS</a> covers Java, Spring Boot, PostgreSQL, and the problems engineers encounter in production. The <a href="https://devrimozcay.gumroad.com/l/oordy">Senior &amp; Staff System Design Interview OS</a> focuses on distributed systems, architecture decisions, and explaining technical trade-offs during senior-level interviews.</p><p>I’m also building <a href="https://docs.google.com/forms/d/e/1FAIpQLScLD53xFU73sirxXmKFfL9-M7FGL_5mM6a8_B0qQdaYce2atA/viewform?usp=header">ProdRescue System Design Lab</a>, a private-beta platform for realistic system design interview practice and technical feedback. Engineers can share the problems they struggle with and request access through the form.</p><p>I write about <strong>production debugging and system design interviews</strong> on <a href="https://substack.com/@devrimozcay1">Substack</a>, including engineering career decisions, backend failures, and the uncomfortable parts of technical hiring that rarely appear in job descriptions.</p><p><em>Devrim Özçay — Founder, ProdRescue AI</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e669863ae82b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/engineering-playbook/i-passed-the-coding-interview-then-they-offered-me-a-junior-engineer-salary-e669863ae82b">I Passed the Coding Interview. Then They Offered Me a Junior Engineer Salary</a> was originally published in <a href="https://medium.com/engineering-playbook">Engineering Under Pressure</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I Did 10 Software Engineer Interviews in 45 Days. One Company Asked Why I Was Still Unemployed]]></title>
            <link>https://medium.com/engineering-playbook/i-did-10-software-engineer-interviews-in-45-days-one-company-asked-why-i-was-still-unemployed-b348b8a29b43?source=rss-94ba01839fc2------2</link>
            <guid isPermaLink="false">https://medium.com/p/b348b8a29b43</guid>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[spring-boot]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[software-architecture]]></category>
            <dc:creator><![CDATA[Software Engineering Review By Devrim]]></dc:creator>
            <pubDate>Wed, 11 Nov 2026 16:29:48 GMT</pubDate>
            <atom:updated>2026-11-11T16:31:20.299Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qTLmgd5WHDR63sLg_xh8cw.png" /></figure><h4><em>I had prepared for Java, Spring Boot, and system design questions. Nobody had prepared me for a hiring manager who wanted to know why nine other companies hadn’t hired me.</em></h4><p>The question came forty minutes into an interview that had been going reasonably well. We’d discussed PostgreSQL locking, RabbitMQ redelivery, and a production incident involving a Spring Boot service that ran out of database connections. The Engineering Manager leaned back in his chair, looked at my résumé, and asked how long I’d been unemployed.</p><p>I told him it had been almost three months. He asked how many companies I’d interviewed with during that time, and I said nine. He looked at me for a moment, then asked why none of them had hired me.</p><p>I laughed because I assumed he was joking. He wasn’t.</p><p>I explained that some companies had selected candidates with different experience, while others hadn’t shared detailed feedback. A few interviews had gone badly, including one where I’d made a mistake in a concurrency exercise. I was trying to give him a reasonable answer without turning the conversation into a guided tour of my recent disappointments.</p><p>He asked whether I thought the problem might be me.</p><p>That was the moment I stopped wanting the job.</p><h3>I’d Been Applying for Jobs Since the Beginning of September</h3><p>My previous position had ended during a period when the company was restructuring its engineering teams. I had some savings, a reasonable amount of professional experience, and the confidence of someone who hadn’t looked for a job in several years. I expected the search to be unpleasant, although I didn’t expect it to become the main activity of my life.</p><p>The first two weeks were encouraging. Recruiters responded to my applications, several companies scheduled screening calls, and the job descriptions looked familiar. Most wanted Java, Spring Boot, PostgreSQL, microservices, and some experience with cloud infrastructure.</p><p>I kept a spreadsheet because I’d already forgotten which recruiter belonged to which company. By the end of September, it contained forty-one applications, six recruiter conversations, and three technical interviews. I’d also received seventeen automated rejections, including one that arrived eleven minutes after I submitted my application.</p><p>The first technical rejection was understandable. The interviewer asked me to implement a bounded queue using Java concurrency primitives, and I made a mistake in the signaling logic. I caught part of the problem while testing, but I ran out of time before I could finish a clean implementation.</p><p>The second was less clear. I’d spent ninety minutes designing a notification service, only to receive feedback that the team wanted someone with stronger distributed systems experience. We’d discussed message ordering, retries, dead-letter queues, and delivery guarantees, so I wasn’t sure which part of my experience had failed to satisfy them.</p><p>The third company never sent feedback. The recruiter told me the hiring manager was traveling and promised an update the following week. Two weeks later, the job posting disappeared.</p><p>By October, I’d stopped expecting the process to be fair or particularly consistent. I still prepared carefully for every interview, but I no longer assumed that a good technical conversation would lead anywhere.</p><h3>The Fifth Company Asked Me to Explain a Gap That Was Still Happening</h3><p>The fifth interview was with a software company building internal tools for retailers. The recruiter had been friendly and unusually direct about the salary range. She also told me the engineering team was small and wanted someone comfortable working on an older Java application while gradually moving services to Spring Boot.</p><p>The technical round went well. I explained how I’d approach migrating a monolithic application without breaking existing workflows, and we discussed database schema changes that needed to remain compatible across deployments. The interviewer seemed particularly interested in how I’d handle a migration when several teams shared the same database.</p><p>During the final conversation, the manager asked why I’d left my previous company.</p><p>I explained the circumstances and described the kind of role I was looking for. He asked whether I’d been actively interviewing since leaving, and I said yes.</p><p>Then he asked whether the gap on my résumé would become a concern if the search continued.</p><p>I wasn’t sure how to answer that. I’d been unemployed for less than three months, and the gap was the result of looking for work. I told him I’d been keeping my technical skills current, building small projects, and preparing for interviews.</p><p>He said he appreciated candidates who remained productive between jobs.</p><p>I nodded, although I was beginning to wonder when unemployment had become a technical competency.</p><p>The company rejected me the following week. The recruiter said the team had selected someone with more direct experience in their industry.</p><p>I didn’t know whether the employment gap had mattered. The manager had spent enough time discussing it that I couldn’t entirely dismiss the possibility.</p><p>After that interview, I began preparing an explanation for being unemployed, as though the absence of a job required a carefully engineered defense.</p><h3>The Seventh Interview Was Conducted by Someone Who Hadn’t Read My Résumé</h3><p>The seventh company was a startup with about thirty employees. Its recruiter had contacted me about a Senior Backend Engineer position and emphasized that the team needed production experience. She mentioned Java, PostgreSQL, AWS, and a planned migration away from a large legacy service.</p><p>The interviewer joined eight minutes late and introduced himself as the CTO. He apologized, opened my résumé during the call, and spent the next few minutes reading it while I waited.</p><p>He asked whether I’d worked with Java before.</p><p>I said yes. It was the first technology listed on my résumé, and I’d been using it professionally for years.</p><p>He asked whether I had experience with Spring Boot.</p><p>I explained that most of my recent backend work involved Spring Boot services. He nodded and asked whether I knew PostgreSQL.</p><p>I began to suspect that we’d accidentally scheduled a recruiter screening with the CTO.</p><p>Eventually, he asked about a production incident I’d handled. I described a RabbitMQ consumer that had repeatedly failed to process certain messages, causing a backlog and delaying downstream operations. We discussed how we’d investigated the failure and why simply increasing consumer concurrency wouldn’t have addressed it.</p><p>He seemed interested for the first time.</p><p>Then his phone rang. He muted himself, answered it, and returned several minutes later.</p><p>He apologized again and asked whether I’d be comfortable working long hours during the company’s upcoming launch.</p><p>I asked what he meant by long hours.</p><p>He said the team was small and everyone needed to be flexible. Sometimes engineers worked evenings and weekends, particularly when customers were waiting for features.</p><p>I asked how frequently that happened and whether the company had an on-call rotation.</p><p>He said they didn’t have a formal rotation because everyone was responsible for production.</p><p>The interview ended after thirty-five minutes. The recruiter contacted me the next day and said the CTO wanted to schedule another conversation.</p><p>I declined.</p><p>It was the first interview process I’d withdrawn from, and I felt guilty for about ten minutes. Then I remembered the CTO asking whether I knew Java while staring at a résumé that contained several years of Java experience.</p><h3>By Interview Nine, I Was Tired of Explaining Myself</h3><p>The ninth company was a financial technology business with a reasonably mature engineering organization. The interview process was demanding but well organized. I completed a Java coding exercise, discussed a payment processing architecture, and answered questions about production incident response.</p><p>The final interviewer was a Director of Engineering who’d spent more than a decade working on financial systems. He asked about my previous responsibilities and wanted to understand how independently I’d made technical decisions.</p><p>I described a collection processing project where I’d helped implement validation rules and asynchronous workflows. He asked which architectural decisions I’d owned and which had been made by more senior engineers. I explained the distinction because I didn’t want to exaggerate my responsibility.</p><p>He seemed satisfied with the answer.</p><p>Near the end, he asked how the job search was going.</p><p>I told him it had been more difficult than I’d expected. I’d reached several technical rounds but hadn’t found the right opportunity.</p><p>He asked whether the experience had changed what I was looking for.</p><p>I said it had. I was paying more attention to the actual responsibilities behind job titles and asking earlier about production ownership, team structure, and expectations.</p><p>He nodded and said he’d seen strong engineers struggle during long searches.</p><p>The company rejected me four days later because another candidate had more experience leading cross-team initiatives. I was disappointed, but the feedback was specific enough to understand.</p><p>That interview stayed with me because the director had asked about my unemployment without treating it as evidence of something suspicious.</p><p>He’d been curious about the search.</p><p>He hadn’t expected me to defend my character.</p><h3>The Tenth Interview Started Like a Normal Technical Discussion</h3><p>The tenth company maintained a large Java platform used by other businesses. Its Engineering Manager, Robert, had previously worked at a bank and seemed familiar with the kind of systems I’d built.</p><p>We spent the first half of the interview discussing transaction processing. He asked how I’d handle a message that had been delivered twice after a consumer crash, and I explained why database constraints and stable business identifiers mattered more than relying on the broker to deliver messages exactly once.</p><p>He asked about a situation where an external provider accepted a payment but our application timed out. I explained that the result would remain uncertain until we could reconcile it and that retrying without provider-side idempotency could create another financial operation.</p><p>Robert asked reasonable follow-up questions. We disagreed briefly about whether a particular workflow needed asynchronous processing, and I explained why I’d want to understand the expected traffic and operational constraints before introducing a broker.</p><p>Then he asked about my employment history.</p><p>I explained that I’d been looking for work for almost three months.</p><p>He asked how many interviews I’d completed.</p><p>I said nine.</p><p>He asked why nobody had hired me.</p><p>At first, I assumed he wanted to know what I’d learned from the process. I described a few technical mistakes and explained that different companies had been looking for different kinds of experience.</p><p>Robert interrupted.</p><p>“Sure, but nine companies have seen your background and decided not to move forward. Doesn’t that tell you something?”</p><p>I asked whether he had a specific concern about my technical performance or experience.</p><p>He said he was trying to understand whether there was a pattern.</p><p>I told him I couldn’t speak for decisions made by other hiring teams. I could explain the feedback I’d received and discuss my experience, but I didn’t have access to the reasoning behind every rejection.</p><p>He looked unconvinced.</p><p>“I’m just trying to understand the risk of hiring someone other companies passed on.”</p><p>I remember looking at the clock in the corner of my screen. We had eighteen minutes left.</p><h3>I Asked Him Whether He Had Any Concerns of His Own</h3><p>I wasn’t angry at first. I was mostly surprised that a hiring manager would use decisions made by unrelated companies as evidence without knowing how those decisions had been reached.</p><p>I asked Robert whether anything in our technical discussion had raised concerns about my suitability for the role. He said my answers had been reasonable, although he wanted someone who could operate independently.</p><p>I asked what independent ownership meant for his team.</p><p>He explained that the Senior Engineer would be responsible for several backend services and expected to make technical decisions without constant supervision. The team had experienced production problems caused by poorly understood dependencies between services.</p><p>That sounded like a normal senior engineering responsibility.</p><p>I explained how I’d handled similar work, including investigating incidents, reviewing transaction boundaries, and coordinating changes with other teams. Robert listened but returned to the interview history.</p><p>He said a candidate who’d been rejected repeatedly might have weaknesses that weren’t immediately visible.</p><p>I told him that was possible. It was also possible that candidates were rejected because of budgets, competing applicants, inconsistent hiring criteria, or experience requirements that differed between companies.</p><p>He asked whether I thought the interview process was unfair.</p><p>I said I thought individual interviews could be useful while still producing imperfect hiring decisions. I’d made mistakes in some of mine, and I wasn’t asking him to ignore that possibility.</p><p>Then I asked whether he’d evaluate my candidacy based on the evidence from our conversation and the responsibilities of the role.</p><p>He said of course.</p><p>But the conversation never really recovered.</p><p>We ended the call politely. I closed my laptop and went for a walk because I didn’t trust myself to write a sensible email immediately afterward.</p><h3>I Didn’t Wait for the Rejection</h3><p>The next morning, I emailed the recruiter and withdrew from the process.</p><p>I explained that the technical discussion had been useful, but the conversation about my previous rejections had left me concerned about how the company evaluated candidates. I said I respected the team’s right to assess hiring risk, although I didn’t believe decisions made by unrelated employers were a reliable substitute for evaluating my experience directly.</p><p>The recruiter called later that afternoon.</p><p>She apologized for the experience and asked whether I’d reconsider. She said Robert could be direct during interviews and sometimes challenged candidates to see how they responded under pressure.</p><p>I told her I understood that technical interviews could involve difficult questions. I’d spent years dealing with production incidents where people asked uncomfortable questions because customers were affected and decisions needed to be made quickly.</p><p>But I didn’t see the value in defending myself against hiring decisions I hadn’t made and couldn’t fully explain.</p><p>She said she’d share my feedback with the hiring team.</p><p>I thanked her for her time.</p><p>After the call, I deleted the interview from my calendar and opened my job application spreadsheet. I’d been treating every completed interview as progress, even when the process made me less interested in working for the company.</p><p>For the first time, I added a column for whether I actually wanted the job after meeting the team.</p><p>It was a surprisingly useful addition.</p><h3>The Next Company Asked About My Unemployment Too</h3><p>A week later, I interviewed with another company hiring a Senior Java Engineer. The recruiter had explained the salary range and team structure before scheduling the technical round. The position involved maintaining Spring Boot services, improving PostgreSQL performance, and helping the team reduce recurring production incidents.</p><p>The technical interviewer asked about a slow API endpoint. We discussed query execution plans, connection pool metrics, and how to distinguish database contention from application-level bottlenecks.</p><p>The conversation went well enough that the company scheduled a final interview with the Engineering Manager.</p><p>Her name was Sarah. She asked about my previous role and why I’d left. I explained the circumstances and mentioned that I’d been interviewing for several months.</p><p>She asked whether the search had been stressful.</p><p>I said yes.</p><p>She laughed and told me she’d spent five months looking for a job earlier in her career. She’d been rejected by a company after six interviews because the hiring team decided to cancel the position.</p><p>We spent a few minutes discussing how unpredictable hiring could be.</p><p>Then she asked what I’d learned from the process.</p><p>I explained that I’d become more careful about understanding the responsibilities behind a Senior Engineer title. I’d also improved how I discussed my production experience, particularly when explaining which decisions I’d personally made and which had belonged to the team.</p><p>Sarah asked about a production mistake I’d made.</p><p>I described a concurrency change that initially improved message throughput but increased database pressure under load. We discussed how we’d identified the problem, rolled back the change, and adjusted the implementation.</p><p>She challenged some of my decisions.</p><p>I answered her questions.</p><p>At no point did she ask me to explain why another company hadn’t hired me.</p><p>The recruiter called the following week with an offer.</p><h3>I Still Think About Robert’s Question</h3><p>I don’t believe a long job search automatically makes someone a better engineer. It can expose technical weaknesses, and repeated interview feedback can reveal patterns worth examining. I learned useful things from several rejections, including areas where my system design explanations were unclear and situations where I’d struggled to communicate ownership.</p><p>But I also saw how much of hiring depended on circumstances outside a candidate’s control. Companies changed budgets, selected people with different experience, canceled positions, and sometimes disappeared without providing feedback.</p><p>Those decisions affected my employment status. They didn’t establish a reliable measure of my engineering ability.</p><p>Robert had asked why nine companies hadn’t hired me. The question sounded simple, but answering it honestly would have required knowing what each hiring team had discussed after I left the call.</p><p>I didn’t have that information.</p><p>Neither did he.</p><p>I sometimes wonder whether I’d have handled the interview differently if I’d been employed at the time. Maybe I’d have challenged the question earlier or ended the conversation when it became clear that my previous rejections were being treated as evidence against me.</p><p>Unemployment changes how you behave in interviews. You become more willing to tolerate awkward questions, unclear responsibilities, and hiring processes that consume entire weekends because you don’t know when the next opportunity will arrive.</p><p>I understand why candidates do it. I did it myself for weeks.</p><p>But the tenth interview made me realize that I was spending so much energy trying to get hired that I’d stopped evaluating whether the companies deserved the same effort.</p><p>The job I eventually accepted wasn’t perfect. The team had technical debt, production incidents, and disagreements about architecture. During my first month, I discovered a Spring Boot service with transaction boundaries that made me question several life choices.</p><p>The difference was that the people interviewing me had been interested in how I’d approach those problems.</p><p>They hadn’t asked me to explain why nine strangers had decided not to employ me.</p><h3>Preparing for Senior Backend Interviews</h3><p>If you’re preparing for Senior Java and backend engineering interviews, my <a href="https://devrimozcay.gumroad.com/l/epxiu">Senior Java &amp; Spring Boot Engineering OS</a> covers Java, Spring Boot, PostgreSQL, and production debugging scenarios. The <a href="https://devrimozcay.gumroad.com/l/oordy">Senior &amp; Staff System Design Interview OS</a> focuses on architecture decisions, distributed systems, and the trade-offs that come up in advanced technical interviews.</p><p>I’m also developing <a href="https://docs.google.com/forms/d/e/1FAIpQLScLD53xFU73sirxXmKFfL9-M7FGL_5mM6a8_B0qQdaYce2atA/viewform?usp=header">ProdRescue System Design Lab</a>, a private-beta platform for realistic system design interview practice and technical feedback. You can share the kinds of problems you’re preparing for and request access through the form.</p><p>I write about <strong>production debugging and system design interviews</strong> on <a href="https://substack.com/@devrimozcay1">Substack</a>, including backend engineering failures, difficult hiring experiences, and the decisions engineers face when systems behave badly.</p><p><em>Devrim Özçay — Founder, ProdRescue AI</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b348b8a29b43" width="1" height="1" alt=""><hr><p><a href="https://medium.com/engineering-playbook/i-did-10-software-engineer-interviews-in-45-days-one-company-asked-why-i-was-still-unemployed-b348b8a29b43">I Did 10 Software Engineer Interviews in 45 Days. One Company Asked Why I Was Still Unemployed</a> was originally published in <a href="https://medium.com/engineering-playbook">Engineering Under Pressure</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I Applied for 64 Software Engineer Jobs in 60 Days. One Interview Made Me Question My Experience]]></title>
            <link>https://medium.com/engineering-playbook/i-applied-for-64-software-engineer-jobs-in-60-days-one-interview-made-me-question-my-experience-26c2e49fd80f?source=rss-94ba01839fc2------2</link>
            <guid isPermaLink="false">https://medium.com/p/26c2e49fd80f</guid>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[system-design-interview]]></category>
            <dc:creator><![CDATA[Software Engineering Review By Devrim]]></dc:creator>
            <pubDate>Wed, 11 Nov 2026 16:26:20 GMT</pubDate>
            <atom:updated>2026-11-11T16:26:20.107Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/388/1*LmWarKBAD4YsA6BFXgLOlQ.png" /></figure><h4><em>I’d been writing production Java for years. Then a 26-year-old engineer asked me a question I couldn’t answer without looking at my old code.</em></h4><p>The interviewer was younger than me, or at least he looked younger. He joined the Google Meet call wearing a faded Metallica shirt, apologized for the noise coming from his apartment, and asked whether I wanted to skip introductions because he’d already read my résumé. I’d been interviewing for almost two months, so I appreciated the efficiency. I had another technical screening scheduled that afternoon and wasn’t particularly interested in hearing how passionate everyone was about solving complex challenges.</p><p>His name was Alex. He’d been working at the company for three years, and according to LinkedIn, he’d graduated from university in 2022. I had more years of professional Java experience than he did, which I noticed immediately and then pretended I hadn’t. Job searching had turned me into someone who compared employment histories with strangers before they’d even asked their first question.</p><p>Alex opened my résumé and pointed to a project I’d listed near the top. It was a payment collection system built with Spring Boot, PostgreSQL, and RabbitMQ. I’d spent nearly two years working on that platform, including a particularly unpleasant period when we were investigating duplicate collection attempts.</p><p>He asked whether I’d been responsible for the idempotency implementation.</p><p>I said yes. I’d worked on the consumer-side changes, helped define the database constraints, and participated in the incident investigation that led to the redesign.</p><p>He nodded and asked a question that sounded almost embarrassingly simple.</p><p>“How did you know the fix actually worked?”</p><p>I started explaining our integration tests. Then I mentioned the unique constraint, the transaction boundaries, and how the consumer handled redelivered messages. Alex listened for a while before asking the same question again.</p><p>“I understand the implementation. What evidence told you the production problem was gone?”</p><p>I opened my mouth and realized I couldn’t remember.</p><h3>I’d Been Telling the Same Story for Three Years</h3><p>The duplicate collection incident was one of the strongest examples on my résumé. It involved real money, an asynchronous processing system, and a failure mode that couldn’t be solved by adding another try-catch block. I&#39;d used it in interviews because it demonstrated the kind of backend experience companies claimed they wanted.</p><p>The original problem was straightforward to describe. A RabbitMQ consumer occasionally received a message more than once after an acknowledgment failure. Under certain conditions, the application could initiate a collection operation without reliably recognizing that an earlier attempt had already progressed.</p><p>We investigated the consumer behavior, reviewed the database state transitions, and changed the workflow to associate collection attempts with stable business identifiers. We also introduced stronger database-level protections so concurrent processing attempts couldn’t independently create the same logical operation.</p><p>I’d explained those details dozens of times. I knew which Spring Boot services were involved, why message acknowledgments mattered, and how PostgreSQL constraints protected us against certain races. If someone asked me to draw the architecture, I could probably do it from memory.</p><p>But Alex wasn’t asking how we’d implemented the fix.</p><p>He wanted to know how we’d verified the result after deployment.</p><p>I told him we’d monitored the service and hadn’t observed the same issue afterward.</p><p>He asked what we’d monitored.</p><p>I mentioned consumer errors, database metrics, and application logs.</p><p>He asked whether we’d tracked duplicate collection attempts as a separate metric.</p><p>I said I wasn’t sure.</p><p>He asked whether we’d reconciled the collection records against the external accounting system.</p><p>I remembered that another team had handled reconciliation, but I couldn’t describe their verification process. I’d been involved in the technical investigation and the code changes. Once the deployment was stable, I’d moved on to the next feature.</p><p>Alex didn’t look disappointed. He simply wrote something in his notes and moved to another question.</p><p>I felt considerably worse than if he’d asked me to implement a lock-free queue.</p><h3>The Previous Seven Interviews Hadn’t Gone Particularly Well</h3><p>By that point, I’d submitted sixty-four applications in sixty days. I’d received a depressing number of automated rejection emails, several recruiter calls that led nowhere, and seven technical interviews that hadn’t produced an offer.</p><p>One company rejected me after a Java coding exercise because I’d missed an edge case involving concurrent updates. Another wanted more experience designing systems that handled millions of requests per second, although its own product appeared to serve a considerably smaller audience. A third asked me to complete a take-home assignment, then stopped responding after I’d submitted it.</p><p>I’d started treating each rejection as a signal that I needed to study something new.</p><p>When I failed the concurrency exercise, I spent three evenings reviewing the Java Memory Model. After the system design rejection, I watched videos about distributed databases and read engineering blogs from companies operating at enormous scale. I even revisited Kubernetes internals because a recruiter had mentioned that another candidate possessed stronger infrastructure experience.</p><p>My preparation notes had grown into a document I barely wanted to open.</p><p>I knew more about some technical subjects than I had when the search began. I was also becoming increasingly uncomfortable discussing the actual work I’d done, because every interview seemed to reveal another detail I couldn’t remember or another decision I hadn’t personally made.</p><p>Alex’s question was different.</p><p>He hadn’t asked about a technology I’d never used. He’d asked about a project I’d spent two years helping build.</p><p>And I couldn’t explain how we’d measured whether our work had succeeded.</p><h3>The Interview Got Worse When He Opened the Pull Request</h3><p>Alex asked whether I still had access to any code samples from my previous work. I explained that the payment platform was proprietary and that I couldn’t share its source code. He said that was fine and asked me to walk through the design from memory.</p><p>I drew the processing flow on the shared whiteboard. An incoming collection request created a durable record, the application published work for asynchronous processing, and a consumer coordinated the collection operation with the relevant database updates. I described the failure cases we’d considered, including duplicate delivery and uncertainty around downstream responses.</p><p>Alex asked where the idempotency key was generated.</p><p>I explained that it came from a stable business identifier associated with the collection operation.</p><p>He asked whether the identifier was unique across retries, partial collections, and different collection types.</p><p>I paused.</p><p>The system supported several collection flows, including principal, interest, and combined operations. Some requests represented distinct business actions against the same credit account, while others were retries of an existing action. A key based only on the credit identifier would have been dangerously broad.</p><p>I told him we’d included operation-specific information in the key.</p><p>He asked exactly which fields.</p><p>I couldn’t remember.</p><p>I’d worked on the implementation, reviewed the relevant code, and discussed the design during the incident. Yet I couldn’t reconstruct the precise uniqueness rule without opening the repository.</p><p>Alex said he wasn’t expecting me to remember every field. He wanted to understand how we’d determined that two requests represented the same business operation.</p><p>That was a much better question.</p><p>I explained the distinction between a repeated technical request and a separate legitimate collection. Two messages could reference the same credit account without being duplicates, while retries of the same collection needed to resolve to the same logical operation. The application had to preserve that distinction even when messages arrived concurrently.</p><p>He seemed satisfied with the reasoning.</p><p>Then he asked whether I’d personally designed that rule or implemented a design agreed upon by the team.</p><p>I told him the truth. The business identity had been defined through discussions involving senior engineers and domain specialists. I’d contributed to the implementation and helped investigate the failure, but I hadn’t independently established the complete business rule.</p><p>He nodded again.</p><p>I was beginning to hate how calmly he accepted my answers.</p><h3>I Had Made My Résumé Sound Better Than My Actual Responsibility</h3><p>After the interview, I opened the PDF version of my résumé and read the section about the payment platform.</p><p>One bullet claimed I’d designed and implemented an idempotent collection processing architecture. Another said I’d eliminated duplicate payment processing through database constraints and asynchronous workflow improvements.</p><p>Both statements were based on work I’d genuinely participated in. But they made my responsibility sound broader and the outcome more certain than I could personally demonstrate.</p><p>I’d helped implement important parts of the solution. I hadn’t owned every architectural decision, and I didn’t have evidence that we’d eliminated every possible duplicate processing scenario. We had addressed the failure modes we’d identified and added safeguards against recurrence.</p><p>That distinction had seemed unimportant when I was writing the résumé.</p><p>It became painfully important when an interviewer started asking specific questions.</p><p>I looked through the rest of the document. Several bullets described team accomplishments as though I’d personally driven them from beginning to end. The technologies were accurate, the projects were real, and the results weren’t invented. But I’d compressed complicated collaborative work into sentences that made ownership look much cleaner than it had been.</p><p>I’d done what countless engineers do when updating their résumés. I’d tried to make the experience sound impressive enough to survive recruiter screening.</p><p>The problem was that I now had to defend every word.</p><h3>The Recruiter Called Two Days Later</h3><p>I expected another rejection. Alex had spent most of the interview examining details I couldn’t remember, and I’d admitted that some of the decisions on my résumé weren’t mine alone.</p><p>Instead, the recruiter said the technical feedback was positive.</p><p>She explained that Alex had appreciated my understanding of payment processing failure modes and my willingness to distinguish my own contributions from the team’s work. He’d raised concerns about how clearly I described the impact of previous projects, but he believed my experience was relevant to the position.</p><p>The company wanted me to meet the Engineering Manager.</p><p>I asked whether Alex had mentioned the questions I couldn’t answer.</p><p>She said he’d noted them, but they hadn’t been the deciding factor. The team was more interested in whether I understood the underlying engineering decisions than whether I could recall implementation details from several years earlier.</p><p>That surprised me.</p><p>I’d spent the previous two days convincing myself that the interview had exposed me as someone who didn’t deserve a senior title. The company apparently had a more measured interpretation.</p><p>I scheduled the final round for the following week.</p><h3>I Spent the Weekend Reconstructing My Own Career</h3><p>I didn’t study LeetCode that weekend. I didn’t review Kafka architecture or watch another video about designing a URL shortener.</p><p>Instead, I went through the projects on my résumé and wrote down what I’d actually done.</p><p>For each project, I tried to remember the original problem, the decisions I’d personally influenced, the implementation work I’d owned, and the evidence we’d used to evaluate the result. I also identified the parts that had belonged to other engineers or teams.</p><p>Some projects were easier to reconstruct than others.</p><p>I remembered a Spring Boot performance issue where we’d discovered that external HTTP calls were holding database connections inside long-running transactions. I could explain the metrics we’d examined, the change we’d made, and how connection acquisition time improved afterward.</p><p>I also remembered a database migration where my contribution had been narrower than my résumé suggested. I’d implemented part of the migration and helped test backward compatibility, but another engineer had designed the rollout strategy and coordinated the dependent services.</p><p>I rewrote that section.</p><p>The new description was less impressive at first glance. It was also something I could explain without quietly hoping the interviewer wouldn’t ask who’d made the important decisions.</p><p>I found a few old performance reports and incident notes that helped me reconstruct the outcomes. For other projects, I couldn’t recover reliable measurements, so I removed claims that implied precise improvements.</p><p>The process was uncomfortable because it forced me to separate the work I’d done from the story I’d been telling about it.</p><p>It also reminded me of things I’d forgotten.</p><p>I’d spent years working on production systems, and many of my most useful contributions hadn’t involved designing a new architecture. They involved identifying a dangerous assumption, finding the cause of an intermittent failure, or preventing a change from introducing another problem.</p><p>Those experiences were harder to turn into glamorous résumé bullets.</p><p>They were also easier to discuss honestly.</p><h3>The Final Interview Started With the Same Project</h3><p>The Engineering Manager, Rachel, had read Alex’s notes. She asked about the payment collection system almost immediately and wanted to understand what I’d learned from the duplicate processing incident.</p><p>I explained the technical failure, the safeguards we’d implemented, and the limits of my responsibility. I also told her that Alex had asked how we’d verified the fix and that I’d realized I couldn’t clearly describe the post-deployment validation.</p><p>Rachel asked what I’d do differently if I encountered the same incident again.</p><p>I said I’d establish explicit verification criteria before considering the incident resolved. For a payment processing problem, that would include measuring duplicate attempts, validating the relevant database invariants, and coordinating reconciliation with the team responsible for the financial records.</p><p>She asked whether I’d be comfortable delaying an incident closure if the service appeared stable but the reconciliation results weren’t available.</p><p>I said the answer depended on what we meant by closure. We could restore normal processing and end the active mitigation phase while keeping the financial reconciliation and corrective actions open. Declaring the entire issue resolved before verifying the business impact would be premature.</p><p>She asked how I’d communicate that distinction to stakeholders.</p><p>I explained that I’d separate service availability from financial correctness. A service could be healthy according to its infrastructure metrics while still requiring investigation into transactions processed during the incident.</p><p>Rachel seemed interested in that answer.</p><p>We spent the rest of the interview discussing ownership, production reliability, and how engineers should communicate uncertainty. She asked about situations where I’d disagreed with a more senior engineer, and I described a database change where I’d raised concerns about locking behavior during deployment.</p><p>I didn’t try to turn myself into the hero of every story.</p><p>Some decisions had been mine. Others hadn’t.</p><p>The conversation felt less like an examination of my résumé and more like a discussion about the work I’d actually done.</p><h3>I Didn’t Get the Job</h3><p>The rejection arrived the following Thursday.</p><p>Rachel had enjoyed the conversation, but the company selected a candidate with more experience independently leading cross-team initiatives. The recruiter said the team had considered me a strong technical candidate and would be open to speaking again if a role with a different scope became available.</p><p>I was disappointed. I’d made it further than in most of my previous interviews, and I’d spent a considerable amount of time preparing for the final round.</p><p>But the feedback didn’t leave me confused.</p><p>The company needed someone who’d already demonstrated a level of cross-team leadership that I couldn’t honestly claim. I had relevant backend experience and had contributed to important production systems, but my strongest examples involved technical ownership within a team.</p><p>I could develop broader leadership experience.</p><p>I couldn’t manufacture it retroactively.</p><p>That evening, I updated my résumé again. I removed two exaggerated ownership claims and rewrote several project descriptions to reflect the work I’d actually performed.</p><p>The document became shorter.</p><p>I was more comfortable sending it to recruiters.</p><h3>The Next Interview Wasn’t Particularly Memorable</h3><p>Two weeks later, I interviewed with a company that maintained a large Java backend for a business-to-business platform. The technical questions covered PostgreSQL performance, Spring Boot transaction behavior, and a production incident involving message redelivery.</p><p>Nothing dramatic happened.</p><p>I explained the systems I’d worked on, answered questions about decisions I’d made, and admitted when a particular responsibility had belonged to someone else. When the interviewer asked how we’d measured the success of a performance improvement, I could describe the metrics because I’d selected an example where I’d been involved in the verification.</p><p>The company invited me to the final round.</p><p>The Engineering Manager asked about my experience working across teams. I explained the scope of my previous responsibilities and described situations where I’d coordinated changes with other engineers. I didn’t claim I’d led an organization-wide migration or independently defined architecture for multiple teams.</p><p>He said the role involved owning several backend services within an established engineering team. The company had Staff Engineers responsible for broader architectural direction, and they wanted someone who could make reliable technical decisions within that structure.</p><p>The responsibilities matched my experience.</p><p>I received an offer the following week.</p><p>I accepted after reviewing the written terms.</p><h3>The Question I Couldn’t Answer</h3><p>I still remember Alex asking how we knew the payment processing fix had worked.</p><p>It was a reasonable question, and I should have been able to answer it more clearly. I’d spent years treating successful deployments as evidence that the engineering work was finished, even when the underlying business problem required additional verification.</p><p>The interview also exposed something about how I’d been presenting my experience. I’d taken collaborative work, compressed it into impressive résumé bullets, and gradually started speaking about those projects as though I’d personally owned every important decision.</p><p>I hadn’t intended to deceive anyone. I wanted recruiters to understand that I’d worked on difficult systems and contributed to meaningful improvements.</p><p>But there was a difference between participating in a successful project and being responsible for every part of its success.</p><p>The first eight interviews had left me convinced that I needed to study more technologies. Alex’s questions made me spend a weekend examining the experience I already had.</p><p>I still believe technical preparation matters. Senior engineers need to understand the systems they’re expected to maintain, and interviews can expose genuine weaknesses in that knowledge.</p><p>But I also learned that an impressive explanation of a production incident means very little if you can’t identify what you personally did, why the team made its decisions, and how anyone knew the problem had been resolved.</p><p>I didn’t get hired by the company where Alex worked.</p><p>I did leave that interview with a much better understanding of my own résumé.</p><p>And the next time someone asked me how I knew a production fix had worked, I had an answer that didn’t begin with a list of Spring Boot annotations.</p><h3>Prepare for Interviews That Go Beyond Framework Questions</h3><p>If you’re preparing for Senior Backend Engineer interviews, my <a href="https://devrimozcay.gumroad.com/l/epxiu">Senior Java &amp; Spring Boot Engineering OS</a> covers Java, Spring Boot, PostgreSQL, and real production engineering problems. For architecture discussions, the <a href="https://devrimozcay.gumroad.com/l/oordy">Senior &amp; Staff System Design Interview OS</a> focuses on distributed systems, reliability, and the technical decisions experienced engineers need to defend.</p><p>I’m also developing <a href="https://docs.google.com/forms/d/e/1FAIpQLScLD53xFU73sirxXmKFfL9-M7FGL_5mM6a8_B0qQdaYce2atA/viewform?usp=header">ProdRescue System Design Lab</a>, a platform for realistic system design interview practice and detailed technical feedback. The private beta form is available for engineers who want to share their preparation challenges.</p><p>I write about <strong>production debugging and system design interviews</strong> on <a href="https://substack.com/@devrimozcay1">Substack</a>, including the hiring experiences, backend failures, and engineering decisions that rarely appear in conventional interview guides.</p><p><em>Devrim Özçay — Founder, ProdRescue AI</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=26c2e49fd80f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/engineering-playbook/i-applied-for-64-software-engineer-jobs-in-60-days-one-interview-made-me-question-my-experience-26c2e49fd80f">I Applied for 64 Software Engineer Jobs in 60 Days. One Interview Made Me Question My Experience</a> was originally published in <a href="https://medium.com/engineering-playbook">Engineering Under Pressure</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I Failed 8 Software Engineer Interviews in 6 Weeks. One Recruiter Finally Told Me Why]]></title>
            <link>https://medium.com/engineering-playbook/i-failed-8-software-engineer-interviews-in-6-weeks-one-recruiter-finally-told-me-why-faf5965f6179?source=rss-94ba01839fc2------2</link>
            <guid isPermaLink="false">https://medium.com/p/faf5965f6179</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[software-architecture]]></category>
            <dc:creator><![CDATA[Software Engineering Review By Devrim]]></dc:creator>
            <pubDate>Wed, 11 Nov 2026 16:23:40 GMT</pubDate>
            <atom:updated>2026-11-11T16:24:32.891Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oDPV5oTr5khlV7naR5PaXA.png" /></figure><h4><em>I thought the problem was my system design answers. Then a recruiter showed me the feedback from an interview I’d considered my best.</em></h4><p>The recruiter called at 4:20 on a Thursday afternoon, and I almost ignored it. I’d spent the morning fixing a Spring Boot application for a take-home assignment, and I wasn’t interested in another conversation about how impressed everyone was with my background. I’d completed eight technical interviews in six weeks, received seven rejections, and was waiting for the eighth company to decide whether I deserved a final round.</p><p>Her name was Rebecca. We’d spoken several times during the process, and she’d been unusually responsive compared with recruiters who disappeared immediately after scheduling an interview. She asked whether I had a few minutes to discuss the team’s feedback.</p><p>I opened my rejection spreadsheet before she finished speaking. The file had become an unpleasant little hobby, with columns for companies, interview dates, technologies, and the reasons people had decided not to hire me.</p><p>Rebecca told me the company wouldn’t be moving forward.</p><p>I thanked her and asked whether the team had identified any technical gaps. She hesitated, then said the interviewers had actually been impressed with my technical knowledge. The concern was something else, and she wanted to explain it because she’d seen similar feedback from another hiring manager.</p><p>“They couldn’t tell when you were answering from experience and when you were answering from something you’d studied.”</p><p>I didn’t understand what she meant. I’d spent years working with Java, Spring Boot, PostgreSQL, and distributed systems. I wasn’t a junior engineer repeating definitions from a tutorial.</p><p>Rebecca explained that the team believed I understood the concepts, but my answers often sounded rehearsed. When interviewers changed the conditions of a problem, I sometimes continued explaining the original solution instead of adapting to the new information.</p><p>I told her I appreciated the feedback. Then I spent the next hour being furious about it.</p><h3>The Interview I Thought I’d Passed</h3><p>The company was hiring a Senior Backend Engineer for a platform that processed financial transactions. Its backend used Java, Spring Boot, PostgreSQL, and RabbitMQ, which made the position one of the better matches I’d found during my search.</p><p>The technical interviewer, a Staff Engineer named Andrew, started with a system design problem. He wanted me to design a service that accepted payment requests and communicated with an external payment provider.</p><p>I’d prepared for exactly this kind of question.</p><p>I explained that each payment request should have an idempotency key, that we’d store the operation in PostgreSQL, and that asynchronous processing could help isolate provider latency from the incoming HTTP request. I described the possible payment states and how a worker could retry operations after temporary failures.</p><p>Andrew asked what would happen if the payment provider accepted a charge but our application timed out before receiving the response.</p><p>I explained that we’d need to treat the outcome as unknown and reconcile it using the provider’s operation reference. Retrying blindly could create duplicate charges if the provider didn’t guarantee idempotent behavior.</p><p>He nodded and changed the problem.</p><p>“Suppose the provider doesn’t offer a status lookup API.”</p><p>I continued explaining reconciliation.</p><p>He interrupted and reminded me that there was no status endpoint. The provider could send a settlement file the following morning, but until then, our application wouldn’t know whether the payment had succeeded.</p><p>I suggested retrying with the same idempotency key.</p><p>Andrew said the provider didn’t support idempotency keys either.</p><p>That should have changed my design considerably. We couldn’t safely assume that repeating the request would produce the same result, and we had no immediate way to confirm the first attempt’s outcome.</p><p>Instead, I kept trying to find a technical mechanism that would make the uncertainty disappear. I discussed distributed locks, database transactions, and retry policies. Andrew listened for a while, then asked whether any of those mechanisms could prevent the external provider from charging the customer twice.</p><p>I admitted they couldn’t.</p><p>He asked what I’d recommend to the business.</p><p>I said we’d need to accept some delay while waiting for reconciliation.</p><p>He asked how I’d explain that to a customer who’d just attempted to pay an invoice.</p><p>I started describing payment states again.</p><p>The interview ended ten minutes later.</p><p>When I reviewed my notes afterward, I considered the discussion successful. I’d covered idempotency, distributed transactions, and reconciliation, and I’d correctly identified the uncertainty around external payment processing.</p><p>Rebecca’s feedback forced me to read the notes differently.</p><p>Andrew had removed the assumptions that made my prepared solution work. I’d recognized the problem intellectually, but I kept reaching for the same architecture because it was the one I’d practiced.</p><h3>I Had Been Preparing Like Every Interview Was an Exam</h3><p>My interview preparation had become almost embarrassingly organized. I had a document containing more than a hundred technical questions, with answers covering Java concurrency, Spring transactions, PostgreSQL indexing, Kafka, RabbitMQ, Redis, and distributed system failure modes.</p><p>Every morning, I’d review a section and practice explaining the concepts aloud. In the afternoon, I’d solve coding problems or draw architecture diagrams. By the evening, I’d usually found another topic that seemed important enough to add to the document.</p><p>I wasn’t wasting my time. The material was relevant, and some of the questions exposed genuine gaps in my understanding. I’d become more comfortable discussing isolation levels, consumer redelivery, and the limitations of distributed locks.</p><p>But I was also developing a habit of recognizing the shape of an interview question and immediately retrieving a prepared answer.</p><p>If someone asked about duplicate messages, I talked about idempotency. If they mentioned slow database queries, I explained indexing and execution plans. A question about system availability triggered a discussion about replication, retries, and circuit breakers.</p><p>The explanations were usually correct in isolation. The trouble started when the interviewer introduced a constraint that made the familiar solution inappropriate.</p><p>I’d become very good at explaining how an architecture worked under the assumptions I’d chosen for it.</p><p>I was less comfortable when someone took those assumptions away.</p><h3>The Fourth Interview Had Already Warned Me</h3><p>Three weeks earlier, I’d interviewed with a company building inventory software for retailers. The interviewer asked how I’d prevent overselling when multiple customers attempted to purchase the last available item.</p><p>I explained optimistic locking with a version column and a conditional update in PostgreSQL. We discussed how concurrent transactions could detect conflicts and why the application needed to handle unsuccessful reservations.</p><p>Then the interviewer asked what I’d do if the same product received thousands of purchase attempts within a few seconds.</p><p>I suggested retrying failed transactions.</p><p>He asked what would happen to database load if thousands of clients repeatedly retried the same contested update.</p><p>I said we’d need backoff and retry limits.</p><p>He asked whether that would solve the customer experience problem.</p><p>I explained that the database would preserve correctness, even if some requests failed.</p><p>He agreed, but said the company was more concerned about how the system behaved during flash sales. Customers were waiting for responses, and the team needed to prevent excessive database contention while still avoiding overselling.</p><p>I started describing Redis.</p><p>He asked whether introducing Redis was necessary to solve the problem.</p><p>I said it depended on the workload.</p><p>He asked me to propose a solution for the workload he’d just described.</p><p>I spent another five minutes discussing possible approaches without choosing one.</p><p>The recruiter rejected me two days later. The feedback said I understood concurrency but struggled to adapt my design to changing requirements.</p><p>At the time, I’d considered that an unfair assessment. I knew several valid ways to handle inventory contention, and the interviewer had kept changing the problem.</p><p>Now I understood why he’d done it.</p><p>He wasn’t looking for a catalog of concurrency mechanisms. He wanted to see how I’d respond when the initial design stopped fitting the requirements.</p><h3>I Called a Friend Who’d Been Interviewing Engineers for Years</h3><p>My friend Mark had been a Staff Engineer for several years and regularly participated in hiring interviews. I sent him the feedback and asked whether he thought it was reasonable.</p><p>He asked me to explain the payment system question.</p><p>I gave him the same answer I’d given Andrew.</p><p>Mark interrupted when I reached the provider that didn’t support idempotency keys or status lookups.</p><p>“What happens if the request times out?”</p><p>I told him the outcome was unknown.</p><p>“Would you retry?”</p><p>I said not automatically.</p><p>“Then what does the customer see?”</p><p>I explained that we’d need to communicate the uncertainty and avoid promising that the payment had failed.</p><p>He asked whether I’d told the interviewer that.</p><p>I admitted I hadn’t explained it clearly.</p><p>Mark asked what the business would need to decide before implementing the workflow.</p><p>I thought about it for a moment. The company would need to define how long customers could remain in an uncertain payment state, whether the provider’s limitations were acceptable, and how support and reconciliation would handle unresolved transactions.</p><p>He asked whether I’d discussed any of those decisions during the interview.</p><p>I hadn’t.</p><p>Mark said something that irritated me because it was difficult to disagree with.</p><p>“You keep answering the engineering question you wish they’d asked.”</p><p>We spent another hour discussing the interviews I’d failed. He didn’t tell me to study harder or memorize a better framework. He asked me to identify the assumptions behind each solution and explain what I’d do when those assumptions no longer held.</p><p>That conversation was more uncomfortable than any technical interview I’d completed.</p><h3>I Stopped Writing Perfect Answers</h3><p>The following weekend, I deleted most of my prepared interview responses. I kept the technical notes because they were useful references, but I stopped practicing complete explanations that I’d try to reproduce during interviews.</p><p>Instead, I asked Mark to challenge my assumptions.</p><p>He’d describe a familiar problem, wait until I proposed a solution, and then change something important. A database might suddenly have a much higher write volume. An external provider might lack the API I’d planned to use. A business requirement might make temporary inconsistency unacceptable.</p><p>Sometimes the new constraint invalidated my entire design.</p><p>At first, I hated it. I’d spend ten minutes constructing a solution, and he’d remove the one condition that made it sensible.</p><p>Eventually, I became more comfortable saying that my original recommendation no longer applied.</p><p>I also started asking questions earlier. Before selecting a message broker, I wanted to understand the expected volume and failure requirements. Before introducing a cache, I wanted to know whether the underlying problem was actually caused by repeated reads.</p><p>When I couldn’t guarantee a business outcome, I said so.</p><p>That last change was particularly difficult. I’d spent years trying to demonstrate competence by solving problems, and it felt strange to explain that some requirements couldn’t be guaranteed with the available infrastructure.</p><p>But pretending a database transaction could control an external payment provider wasn’t competence.</p><p>It was wishful thinking with SQL.</p><h3>The Ninth Interview Was About a Problem I Couldn’t Fully Solve</h3><p>The next company operated a platform for booking appointments. Its backend used Java and PostgreSQL, and the technical interview involved designing a reservation system that prevented double bookings.</p><p>The interviewer, a Senior Engineer named Olivia, asked how I’d handle two customers attempting to reserve the same appointment slot.</p><p>I described a database constraint that would prevent conflicting confirmed reservations. We discussed transaction boundaries and how the application would handle a failed attempt when another customer had already secured the slot.</p><p>Then she introduced a new requirement.</p><p>Customers could reserve a slot temporarily while completing payment. The reservation would expire after ten minutes if payment wasn’t completed.</p><p>I explained how we’d represent temporary holds and expiration times, then discussed the database operations required to convert a valid hold into a confirmed reservation.</p><p>Olivia asked what would happen if the payment provider took eleven minutes to confirm a successful charge.</p><p>I said we’d need to define how the booking system handled late payment confirmations. We couldn’t assume that an expired reservation was still available, and we shouldn’t silently confirm a booking that might already belong to someone else.</p><p>She asked whether I’d automatically refund the customer.</p><p>I said that could be one policy, but I’d want to understand the business rules and the payment provider’s capabilities. Depending on the workflow, we might also be able to extend holds while a payment was genuinely pending, although that would introduce other operational trade-offs.</p><p>Olivia asked what I’d recommend for the initial version.</p><p>I suggested a conservative approach that avoided double bookings, made payment uncertainty visible, and provided a defined recovery path for customers whose payments succeeded after their holds expired. I explained the limitations and what we’d need to monitor after launch.</p><p>She challenged the design several times.</p><p>I changed parts of it when her constraints made the original choices inappropriate.</p><p>The conversation lasted seventy minutes, and I left with a list of things I would have wanted to investigate further. I hadn’t produced a perfect architecture, and I wasn’t entirely satisfied with my answer about late payment confirmations.</p><p>The recruiter invited me to the final round the following day.</p><h3>The Final Interview Didn’t Feel Like a Performance</h3><p>The Engineering Manager asked about a production incident I’d handled. I described a Spring Boot service where database connections had become exhausted during peak traffic. We initially suspected insufficient pool capacity, but investigation showed that some transactions remained open while waiting for an external service.</p><p>He asked whether we’d increased the connection pool.</p><p>I said we’d considered it, but the metrics suggested that longer transaction duration was the primary issue. Increasing the pool could have delayed the symptoms without addressing the underlying cause.</p><p>He asked whether I’d personally made the decision.</p><p>I explained my role in the investigation and said the final deployment decision had been made with the incident lead. I’d recommended changing the transaction boundaries after confirming the affected business operations would remain consistent.</p><p>He asked what I’d have done if the incident lead disagreed.</p><p>I said I’d explain the evidence, the risks of the alternatives, and the customer impact. If the decision remained with the incident lead, I’d make sure the disagreement and rollback criteria were clear rather than pretending I had authority I didn’t possess.</p><p>The manager asked several follow-up questions about ownership and collaboration. I answered them without trying to turn every example into a story where I’d saved the company.</p><p>At the end, he asked whether I had any questions.</p><p>I asked what kinds of technical decisions the team expected a Senior Engineer to make independently and which ones required broader agreement. He explained that engineers owned their services but were expected to involve other teams when changes affected shared infrastructure or customer-facing behavior.</p><p>It sounded like a reasonable arrangement.</p><p>The recruiter called four days later with an offer.</p><h3>I Read Rebecca’s Feedback Again</h3><p>After accepting the offer, I opened the email Rebecca had sent following my eighth rejection. I’d kept it because she’d taken the time to explain something most recruiters would have reduced to a generic sentence about moving forward with other candidates.</p><p>Her feedback hadn’t said I lacked technical knowledge. It said the interviewers struggled to see how I’d adapt when the problem changed.</p><p>That was a fair criticism of several answers I’d given.</p><p>I had been so focused on demonstrating expertise that I’d sometimes defended solutions after the assumptions supporting them had disappeared. When an interviewer introduced a new constraint, I treated it as another obstacle to overcome with technology rather than information that might require a different decision.</p><p>I still believe some interview questions are poorly designed. Companies sometimes ask candidates to solve unrealistic problems under arbitrary time limits, and interviewers aren’t always consistent about what they expect. A rejection doesn’t automatically mean the candidate made a mistake.</p><p>But the feedback from my interviews had formed a recognizable pattern. Different companies had noticed the same weakness, even when they described it differently.</p><p>I’d spent six weeks trying to become the candidate who knew the answer to every question.</p><p>The interview that finally worked was the one where I stopped pretending every question had a complete technical solution.</p><h3>What I Wish I’d Understood Before Interview One</h3><p>I still prepare for interviews. I review Java concurrency, Spring Boot transactions, PostgreSQL behavior, and distributed systems because those subjects matter in the jobs I want. I also practice explaining production incidents and architectural decisions, particularly the ones that didn’t work as expected.</p><p>The difference is that I no longer treat a prepared answer as something I need to deliver intact.</p><p>When an interviewer changes the requirements, I reconsider the design. If the new constraint makes my recommendation unsafe, I say so and explain what I’d need to change.</p><p>Sometimes I ask for more information because the decision genuinely depends on something the interviewer hasn’t specified. Other times I make a reasonable assumption and proceed, knowing that the interviewer may challenge it.</p><p>That approach doesn’t guarantee an offer. It does make the conversation closer to the engineering work I actually do, where requirements change, external systems behave badly, and nobody gets to choose all the constraints.</p><p>I remember being angry when Rebecca told me my answers sounded rehearsed. I’d worked hard to prepare, and it felt as though the company was criticizing me for taking the interview seriously.</p><p>Looking back, I understand what the team was trying to evaluate.</p><p>They already knew I could explain distributed transactions.</p><p>They wanted to know what I’d do when the transaction couldn’t solve the problem.</p><h3>Prepare for Senior Engineering Interviews With Real Constraints</h3><p>If you’re preparing for advanced backend interviews, my <a href="https://devrimozcay.gumroad.com/l/oordy">Senior &amp; Staff System Design Interview OS</a> focuses on architecture trade-offs, distributed systems, consistency, and the decisions engineers face when requirements conflict. For Java-specific preparation, the <a href="https://devrimozcay.gumroad.com/l/epxiu">Senior Java &amp; Spring Boot Engineering OS</a> covers Spring Boot, PostgreSQL, concurrency, and production engineering scenarios.</p><p>I’m also developing <a href="https://docs.google.com/forms/d/e/1FAIpQLScLD53xFU73sirxXmKFfL9-M7FGL_5mM6a8_B0qQdaYce2atA/viewform?usp=header">ProdRescue System Design Lab</a>, a platform for realistic system design interview practice and technical feedback. Engineers can share their preparation challenges and request access to the private beta.</p><p>I write about <strong>production debugging and system design interviews</strong> on <a href="https://substack.com/@devrimozcay1">Substack</a>, including the technical decisions, hiring experiences, and engineering failures that rarely appear in conventional interview guides.</p><p><em>Devrim Özçay — Founder, ProdRescue AI</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=faf5965f6179" width="1" height="1" alt=""><hr><p><a href="https://medium.com/engineering-playbook/i-failed-8-software-engineer-interviews-in-6-weeks-one-recruiter-finally-told-me-why-faf5965f6179">I Failed 8 Software Engineer Interviews in 6 Weeks. One Recruiter Finally Told Me Why</a> was originally published in <a href="https://medium.com/engineering-playbook">Engineering Under Pressure</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I Did 12 Software Engineer Interviews in 7 Weeks. The Best One Lasted 19 Minutes]]></title>
            <link>https://medium.com/engineering-playbook/i-did-12-software-engineer-interviews-in-7-weeks-the-best-one-lasted-19-minutes-790cadb78b44?source=rss-94ba01839fc2------2</link>
            <guid isPermaLink="false">https://medium.com/p/790cadb78b44</guid>
            <category><![CDATA[software-architecture]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[java]]></category>
            <dc:creator><![CDATA[Software Engineering Review By Devrim]]></dc:creator>
            <pubDate>Wed, 11 Nov 2026 16:21:51 GMT</pubDate>
            <atom:updated>2026-11-11T16:22:20.469Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rp8BMW2ej5zsr7y_VIL4wA.png" /></figure><h4><em>I’d spent nearly two months preparing for difficult technical interviews. Then a hiring manager ended our conversation before I could finish my second example.</em></h4><p>The interviewer closed his notebook nineteen minutes into our scheduled hour. I was halfway through explaining a production incident involving a Spring Boot service, and I assumed he’d lost interest. He thanked me for my time, said he had enough information, and told me the recruiter would contact me shortly. I’d been rejected often enough to recognize what I thought was happening.</p><p>I didn’t argue. I finished the sentence, thanked him, and left the call. Then I opened the spreadsheet where I’d been recording my job applications and wrote <em>probably rejected</em> beside the company’s name. It was my twelfth interview in seven weeks, and I was getting tired of pretending that every conversation had been an exciting opportunity.</p><p>The recruiter called ninety minutes later. She said the manager wanted to move forward and asked whether I was available for the next round. I asked if she’d received the correct feedback because the interview had lasted less than twenty minutes. She laughed and said he’d written that I was one of the clearest candidates he’d spoken to that month.</p><p>That bothered me more than it should have. I’d spent weeks failing interviews that lasted ninety minutes, and somehow the shortest conversation had produced the strongest feedback. I went back through my notes that evening because I wanted to understand what I’d done differently.</p><p>The answer wasn’t flattering.</p><h3>The Interview Where I Talked for Eleven Minutes Without Answering the Question</h3><p>Three weeks earlier, I’d interviewed with a financial technology company looking for a Senior Java Engineer. The technical round started with a question about a payment API receiving duplicate requests. I’d worked on similar systems, so I felt comfortable discussing the problem.</p><p>The interviewer asked how I’d prevent the same payment from being processed twice. I started explaining RabbitMQ delivery guarantees, transaction isolation, database uniqueness constraints, and why distributed locks were often more complicated than people expected. I drew a diagram showing a consumer, a PostgreSQL database, and an external payment provider.</p><p>About ten minutes later, he interrupted.</p><p>“That’s useful, but I asked about the API. The request hasn’t reached RabbitMQ yet.”</p><p>He was right. I’d recognized a familiar category of problem and started explaining everything I knew about it. The interviewer wanted to understand how I’d handle duplicate HTTP requests at the boundary of the system.</p><p>I eventually described a stable idempotency key, a durable record of the operation, and the need to return a consistent result when a client retried the same request. We discussed what should happen if the first request was still processing and why a unique constraint needed to protect the operation against concurrent requests.</p><p>The answer took another fifteen minutes because I kept returning to details that weren’t relevant.</p><p>The interviewer didn’t seem annoyed. He asked a few follow-up questions and ended the call politely. The recruiter rejected me four days later, explaining that the team had concerns about the clarity and structure of my technical communication.</p><p>I dismissed the feedback at first. I’d answered the question correctly, and I couldn’t understand why they cared so much about the route I’d taken to get there.</p><p>That was becoming a familiar problem.</p><h3>My Preparation Notes Were Getting Bigger Than My Answers Needed to Be</h3><p>I’d been preparing for interviews almost every day. My laptop had a folder containing Java concurrency notes, Spring Boot transaction examples, PostgreSQL execution plans, and diagrams of distributed systems. I also had a document with behavioral interview questions and stories from production incidents I’d handled.</p><p>The material was useful. I understood more about some subjects than I had before starting the job search, particularly around transaction boundaries and failure recovery. But I was also developing a strange habit of trying to include everything I’d studied whenever an interviewer asked something remotely related.</p><p>If someone mentioned caching, I wanted to explain Redis eviction policies. A question about database performance became an opportunity to discuss connection pooling, indexing, and query planning. When an interviewer asked about a production outage, I sometimes spent so long describing the architecture that we barely reached the actual incident.</p><p>I was afraid of leaving out the detail that would prove I was senior enough.</p><p>During my seventh interview, a Staff Engineer asked me how I’d investigate a slow endpoint. I explained how I’d examine application metrics, database queries, and downstream service latency. He asked which one I’d check first.</p><p>I gave him a lengthy explanation about why the answer depended on the architecture.</p><p>He waited until I finished.</p><p>“Assume you have access to production metrics and the endpoint became slow ten minutes ago. Where do you start?”</p><p>I told him I’d check recent deployments and traces for the affected requests.</p><p>He nodded.</p><p>“Good. That’s what I wanted to know.”</p><p>We’d spent several minutes reaching an answer that could have taken twenty seconds.</p><p>I received another rejection later that week. The feedback mentioned that my technical knowledge was strong but my answers sometimes lacked focus.</p><p>By then, I’d heard variations of that criticism from three companies. I still thought the solution was more preparation.</p><h3>The Ninth Interview Was the Most Embarrassing</h3><p>The ninth company was building software for warehouse operations. Its backend used Java, PostgreSQL, and Kafka, and the interview involved designing a service that tracked inventory across multiple locations.</p><p>The interviewer asked how I’d prevent two customers from purchasing the last available item simultaneously. I described database transactions and locking, then explained optimistic concurrency control and how a version column could detect conflicting updates.</p><p>He asked whether optimistic locking was always the right choice.</p><p>I said no and began discussing contention, retry behavior, and pessimistic locking. Then I moved into distributed locks and why Redis-based coordination could be risky if the application relied on it for correctness.</p><p>The interviewer interrupted and asked how I’d choose between the approaches for their workload.</p><p>I realized I didn’t know the workload.</p><p>I’d spent almost fifteen minutes comparing concurrency mechanisms without asking how frequently inventory conflicts occurred, whether reservations were required, or what the business expected when two customers attempted to purchase the same item.</p><p>I asked about those details. He explained that the system processed moderate traffic but experienced short bursts of contention during promotions. Overselling was unacceptable, and the business preferred occasionally rejecting a reservation over accepting an order it couldn’t fulfill.</p><p>That gave us enough information to discuss a concrete design. We talked about conditional database updates, reservation records, and the trade-offs involved in retrying failed operations. The conversation improved considerably once I stopped explaining technologies in isolation.</p><p>Unfortunately, the interview had already consumed most of its allotted time.</p><p>The recruiter rejected me the next morning.</p><p>I closed the email and stared at my notes. I’d studied optimistic locking for years, used it in real applications, and could explain the relevant SQL. Yet I’d struggled to answer a question that depended on understanding the business constraints before selecting an implementation.</p><p>I was starting to suspect that knowing too many possible answers was making me reluctant to choose one.</p><h3>The Twelfth Interview Started With a Question About a Bad Deployment</h3><p>The company was a small SaaS business with a backend team of six engineers. Its product handled recurring billing for other businesses, and the job description mentioned Java 21, Spring Boot, PostgreSQL, and production ownership. I wasn’t particularly excited about the role because the previous eleven interviews had exhausted most of my enthusiasm.</p><p>The hiring manager, Michael, joined the call two minutes late. He apologized and explained that he’d been helping another engineer investigate a deployment issue. I told him I understood, and he laughed when I said production rarely respected calendar invitations.</p><p>He asked about the most difficult deployment problem I’d encountered.</p><p>Normally, I would have started by explaining the system architecture. This time, I described the problem first.</p><p>We’d deployed a change that increased message-processing concurrency in a Spring Boot service. Throughput improved initially, but database connection usage rose sharply, and some requests began timing out. We rolled back the change, investigated the interaction between consumer concurrency and transaction duration, and adjusted the implementation before trying again.</p><p>Michael asked why we’d increased concurrency in the first place.</p><p>I explained that the message backlog had been growing during peak traffic, and we’d assumed additional consumers would help. We hadn’t adequately accounted for the database work performed by each message.</p><p>He asked whether I had supported the change.</p><p>I said yes.</p><p>He asked what I’d do differently.</p><p>I told him I’d establish the downstream capacity limits before increasing parallelism and define rollback conditions using metrics that reflected the entire workflow. I’d also test the change under a representative workload instead of assuming the consumer was the only bottleneck.</p><p>Michael nodded and wrote something down.</p><p>Then he asked how I’d handle a similar situation if the team was under pressure to release a customer-facing feature.</p><p>I said I’d first want to know whether the performance issue was causing customer harm and whether the feature depended on the affected service. If the incident was active, I’d prioritize stabilizing the system and make the trade-off explicit to the product team rather than quietly allowing both pieces of work to compete for the same engineers.</p><p>He asked one more question about PostgreSQL connection pools. I explained why increasing the pool size could make matters worse if the database was already saturated and how I’d distinguish pool exhaustion from slow query execution.</p><p>He closed his notebook.</p><p>I checked the clock.</p><p>Nineteen minutes.</p><h3>I Thought He’d Decided I Wasn’t Good Enough</h3><p>When Michael said he had enough information, I assumed he’d found a problem with my answers. The interview was scheduled for an hour, and we’d barely covered Java. He hadn’t asked me to write code, explain transaction propagation, or design a distributed system.</p><p>I thanked him and asked whether he had any questions about my background that I hadn’t addressed.</p><p>He said no. He’d read my résumé and wanted to understand how I approached production problems, particularly when a change I’d supported caused unexpected consequences. He said the team could evaluate specific Java knowledge in the next round.</p><p>I left the call feeling strangely disappointed. I’d prepared for a difficult technical interview, and the manager hadn’t given me much opportunity to demonstrate what I knew.</p><p>Then the recruiter called.</p><p>She said Michael wanted to move forward and had specifically mentioned that I’d explained the incident clearly, acknowledged my role in the decision, and described what I’d learned without blaming the team.</p><p>I asked whether the short interview was normal.</p><p>She said Michael often finished early when he had enough evidence to make a decision about the next stage. Other candidates had spent most of the hour describing their technology stacks without getting to the situations he’d asked about.</p><p>I thanked her and scheduled the next interview.</p><p>After the call, I opened the notes from my previous eleven interviews. For the first time, I wasn’t looking for technical questions I’d answered incorrectly.</p><p>I was looking at how long I’d spent answering them.</p><h3>I Listened to My Own Answers</h3><p>I’d recorded a few practice interviews with a friend earlier in the job search. That evening, I watched one of them.</p><p>My friend had asked me to explain a production incident involving PostgreSQL connection exhaustion. I spent four minutes describing the service architecture, the database configuration, and the request flow before mentioning that customers were experiencing timeouts.</p><p>Then I explained the investigation in exhaustive detail. I talked about HikariCP metrics, thread dumps, transaction boundaries, and how we’d identified an external HTTP call occurring inside a database transaction.</p><p>The technical information was accurate.</p><p>But after twelve minutes, I still hadn’t explained what I’d personally done, which decision we’d made, or whether the fix had worked.</p><p>I watched another recording. The pattern was similar. I treated every question as an invitation to deliver a complete technical lecture, even when the interviewer wanted a specific example or recommendation.</p><p>It was uncomfortable to watch because I recognized the behavior immediately. I’d been so concerned about demonstrating expertise that I’d made it difficult for interviewers to understand my actual experience.</p><p>The nineteenth-minute interview had been different because I was tired enough to stop performing. I’d answered the questions directly, admitted that I’d supported a decision that caused problems, and explained the consequences.</p><p>I hadn’t tried to make the incident sound more impressive than it was.</p><h3>The Next Round Wasn’t Easy</h3><p>The second interview was with a Staff Engineer named Rachel. She asked me to design a service that processed subscription renewals and handled payment provider failures. We spent over an hour discussing idempotency, transaction boundaries, and how to reconcile payments when the provider returned an ambiguous result.</p><p>At one point, Rachel asked whether I’d use RabbitMQ for the processing workflow.</p><p>I said it could be appropriate, particularly if the company already operated it, but I’d want to understand the expected volume and failure requirements before introducing another component. I explained that a database-backed worker might be sufficient for a smaller workload.</p><p>She asked how I’d prevent duplicate processing.</p><p>I described the database invariant first, then explained how the message-processing mechanism would interact with it. We discussed concurrency, retries, and the difference between preventing duplicate internal operations and preventing duplicate charges at the provider.</p><p>The conversation lasted seventy-five minutes. I didn’t answer everything perfectly, and Rachel challenged several decisions. But I noticed that we spent more time evaluating the design and less time trying to establish what question I was answering.</p><p>The final interview was with the Engineering Director. He asked about disagreements, mentoring, and how I’d respond when a product deadline conflicted with reliability work. I used specific examples and explained where I’d made mistakes instead of presenting every situation as a successful demonstration of leadership.</p><p>The recruiter called four days later with an offer.</p><p>I accepted after reviewing the written terms.</p><h3>The Strange Part Was How Little My Technical Knowledge Had Changed</h3><p>Between the ninth rejection and the offer, I hadn’t completed another course or learned a new framework. I still used the same Java, Spring Boot, PostgreSQL, and distributed systems knowledge I’d brought to the earlier interviews. There were technical areas I needed to improve, and I continued studying them after accepting the job.</p><p>The difference was how I used that knowledge in conversation.</p><p>I stopped treating every interview question as a test of how much information I could recall. When someone asked about an incident, I explained the incident. When they asked for a decision, I made a recommendation and described the assumptions behind it.</p><p>If they wanted deeper technical detail, they asked.</p><p>That approach also made it easier to recognize questions I couldn’t answer. Instead of filling the silence with related concepts, I could explain what I knew, identify what was missing, and describe how I’d investigate.</p><p>I don’t think the first eleven companies were wrong to reject me. Some needed different experience, some had stronger candidates, and a few interviews simply went badly. I also don’t believe every hiring manager would have evaluated my answers the same way Michael did.</p><p>But the feedback I’d received was consistent enough that I couldn’t ignore it. Several interviewers had struggled to follow my answers despite acknowledging my technical knowledge.</p><p>I’d interpreted that as evidence that I needed to know more.</p><p>In reality, I needed to make the knowledge I already had easier to evaluate.</p><h3>What I Remember About Those Nineteen Minutes</h3><p>I remember Michael joining the call late and apologizing for the deployment problem. I remember describing a concurrency change that had caused database timeouts and admitting that I’d supported the decision. I remember him asking what I’d do differently and accepting my answer without requesting a twenty-minute explanation of HikariCP internals.</p><p>I also remember the silence after he closed his notebook.</p><p>At the time, I thought the interview had ended because I wasn’t good enough. I’d become so accustomed to rejection that I interpreted an ordinary hiring decision through the worst possible explanation.</p><p>The interview turned out to be the beginning of an offer process, although I had no way of knowing that when I left the call.</p><p>Seven weeks of preparation had made me better at explaining technical concepts. It had also made me increasingly anxious about proving that I deserved a Senior Engineer title.</p><p>The shortest interview of the entire search happened when I finally stopped trying to prove everything at once.</p><p>I still keep the old preparation notes. They’re useful when I need to revisit transaction isolation or understand a Java concurrency problem.</p><p>I just don’t read them aloud when someone asks what happened during a bad deployment.</p><h3>Prepare for the Interviews That Actually Test Engineering Experience</h3><p>If you’re preparing for advanced backend interviews, my <a href="https://devrimozcay.gumroad.com/l/epxiu">Senior Java &amp; Spring Boot Engineering OS</a> covers Java, Spring Boot, PostgreSQL, and practical production engineering problems. The <a href="https://devrimozcay.gumroad.com/l/oordy">Senior &amp; Staff System Design Interview OS</a> focuses on architecture decisions, distributed systems, and the trade-offs experienced engineers need to explain.</p><p>I’m also developing <a href="https://docs.google.com/forms/d/e/1FAIpQLScLD53xFU73sirxXmKFfL9-M7FGL_5mM6a8_B0qQdaYce2atA/viewform?usp=header">ProdRescue System Design Lab</a>, a platform for realistic system design interview practice and technical feedback. The private beta form is open for engineers who want to share their preparation challenges and help shape the platform.</p><p>I write about <strong>production debugging and system design interviews</strong> on <a href="https://substack.com/@devrimozcay1">Substack</a>, with practical discussions about backend architecture, hiring experiences, and engineering decisions that rarely appear in standard interview guides.</p><p><em>Devrim Özçay — Founder, ProdRescue AI</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=790cadb78b44" width="1" height="1" alt=""><hr><p><a href="https://medium.com/engineering-playbook/i-did-12-software-engineer-interviews-in-7-weeks-the-best-one-lasted-19-minutes-790cadb78b44">I Did 12 Software Engineer Interviews in 7 Weeks. The Best One Lasted 19 Minutes</a> was originally published in <a href="https://medium.com/engineering-playbook">Engineering Under Pressure</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>