Six Common Mistakes Junior Developers Make and How to Overcome Them
Eric Roby
Summary:
This video identifies six key mistakes that developers often make early in their careers and the lessons learned from them:
- 1. The Deploy: Failing to test edge cases, leading to real-world financial losses despite code working on the "happy path."
- 2. The Wrong Layer: Debugging inefficiently by relying on print statements rather than using proper debuggers or examining the correct layer (e.g., HTTP headers) for complex issues.
- 3. The Scroll: Blindly trusting ORMs without understanding the underlying SQL queries, resulting in performance bottlenecks like the N+1 query problem.
- 4. Expensive Mistake: Neglecting to handle failure paths and implement alerts, which can lead to cascading infrastructure costs and undetected issues.
- 5. Week That Never Shipped: Over-engineering solutions and failing to clarify requirements, leading to wasted time building complex systems when simpler, existing tools would suffice.
- 6. Two Days, Two Characters: Hesitating to ask for help, wasting significant time on easily solvable problems, but also overcorrecting by asking too many questions without prior research.
The overarching lesson is that becoming a senior developer involves learning from painful experiences and balancing self-sufficiency with seeking help.
Introduction [00:00]
The video shares six common signs that indicate a developer might still be thinking like a junior. These are not insults but opportunities for growth, as every senior developer has likely made similar mistakes. The first three signs are personal stories from the presenter, while the last three are derived from a LinkedIn poll with submissions from other developers.
1. The Deploy: Neglecting Edge Case Testing [00:53]
- The Mistake: As a junior developer, the presenter built a bulk discount feature for a manufacturing company, ensuring it worked for the "happy path" (a single discount). They deployed the code confidently without considering how users might interact with it unexpectedly.
- The task was to implement a "buy three or more items, get 15% off" discount.
- The code passed tests and code review, and was deployed quickly.
- The Consequence: The next day, support tickets emerged because customers were receiving double discounts, leading to thousands of dollars in losses.
- The presenter realized they never tested for a scenario where an individual could add two discounts to an order.
- The Lesson Learned: Making code work is the bare minimum. The actual job involves creating code that is resilient and can survive real users in a production environment, requiring thorough testing for various edge cases and unexpected behaviors.
2. The Wrong Layer: Inefficient Debugging Practices [02:25]
- The Mistake: The presenter relied solely on
console.log or print statements for debugging, scattering them throughout functions to trace data flow, instead of using a debugger or examining the correct layer where the error was occurring.
- They spent hours adding logs, and their local environment logs showed the code working perfectly.
- The Consequence: The bug persisted in production because the issue was authentication-related, occurring at the API response layer, not within the application logic as observed locally.
- The legacy system returned a 200 HTTP status code even when the API call failed on authentication, misleading the developer.
- The local environment used a mock JWT, while production required a real session, leading to the authentication failure.
- The Lesson Learned: Debugging isn't about volume but about understanding the problem and using the right tools. Developers should learn to use debuggers, proper telemetry, and examine logs and HTTP headers to pinpoint issues accurately, especially when differences exist between local and production environments.
3. The Scroll: Blindly Trusting ORMs [04:58]
- The Mistake: Building a content management platform, the presenter used Hibernate (an ORM with Java) to fetch articles, authors, and tags, completely trusting the ORM to handle SQL generation without inspecting it.
- The developer explicitly avoided looking at the generated SQL queries, assuming the ORM would manage database interactions efficiently.
- The Consequence: The article page took 45 seconds to load in QA, revealing an N+1 query problem in the database logs.
- The system was performing hundreds of database queries for a single page load: one query for articles, then separate queries for each author, and then separate queries for each tag, totaling 600 queries for 200 articles.
- This effectively led to a self-inflicted Distributed Denial of Service (DDoS) on their own database.
- The Lesson Learned: While ORMs abstract database layers, developers must still understand the underlying mechanics (SQL) to prevent performance issues like N+1 queries. It's crucial not to blindly trust abstractions but to verify their efficiency and use features like joins when appropriate.
4. Expensive Mistake: Overlooking Failure Paths and Alerting [07:19]
- The Mistake: A backend developer tasked with improving Stripe webhook handling focused only on the "payment succeeded" path, neglecting the "payment failed" scenario. They also lacked proper alerting mechanisms.
- The code was designed for subscription activation on successful payment.
- The failure path was treated as a minor edge case, not a primary concern.
- The Consequence: When a customer's credit card was declined, the code threw an unhandled exception, causing the Stripe webhook to return a 500 error. Stripe then retried the webhook dozens of times over 72 hours.
- Each retry triggered a lambda function that failed but still hit the database and inventory system.
- This led to a "noticeably higher" AWS bill due to infrastructure costs and went undetected for days due to the absence of alerts.
- The Lesson Learned: The "happy path" is often the least important and most tested. Crucially, focus on failure paths and edge cases, as these are the ones that can break a business, incur significant costs, and go unnoticed without robust error handling and alerting systems.
5. Week That Never Shipped: Over-engineering without Clarification [10:16]
- The Mistake: A junior developer received a ticket to "Add user analytics tracking" and, eager to impress, immediately started building a custom, complex system (event schemas, collecting APIs, scheduling jobs, basic dashboard) without asking clarifying questions.
- The developer believed great developers "just figure things out" and felt asking questions was a sign of weakness.
- They spent a week writing thousands of lines of clean, tested, and documented code.
- The Consequence: Upon demoing, the manager's first question was "Why didn't you just use Google Analytics?" The marketing team only needed to track three simple events (sign-up, upgrades, cancellations), which could have been done in an hour with existing tools.
- The entire week's work was never shipped.
- The Lesson Learned: Before undertaking any significant task, ask clarifying questions: "What problem am I solving?", "Is there an existing solution?", and "What's the simplest thing that works?" This "30-minute rule" encourages planning and understanding requirements to avoid over-engineering and wasted effort.
6. Two Days, Two Characters: Balancing Seeking Help and Self-Sufficiency [12:19]
- The Mistake: An eight-month experienced developer spent two days troubleshooting a "connection refused" error when a Docker container tried to connect to PostgreSQL on
localhost.
- They tried numerous solutions (Stack Overflow, Docker docs, rebuilding containers, reinstalling Docker) but hesitated to ask for help, believing senior developers "knew everything."
- The Consequence: A senior developer solved the issue in 10 seconds by pointing out that
localhost inside a container refers to the container itself, not the host machine; the fix was to change localhost to DB. The junior then overcorrected, asking too many questions without prior research.
- The Lesson Learned: Asking for help is not admitting defeat but optimizing for results. However, there's a balance. Developers should first attempt to research and troubleshoot independently (e.g., by Googling) to foster learning, but also know when to seek guidance from experienced colleagues to avoid excessive time waste. The gap between junior and senior isn't just intelligence or years of experience, but an accumulation of painful lessons and the wisdom to know when to be self-sufficient and when to collaborate.