Don’t generalize people, generalize the code!

Aleksandar Danilovic
Javarevisited
Published in
4 min readMar 11, 2024

How I failed the coding interview writing perfectly efficient and working, but unmaintainable code

Photo by Markus Spiske on Unsplash

In the world of software development, the journey of learning and growth is often marked by memorable experiences that shape our understanding and approach to coding. One such story is a coding interview that offered me a profound lesson on the importance of code readability.

The challenge was seemingly straightforward: to write a routine that converts Roman numerals to integers. Armed with my coding skills and a logical approach, I crafted a solution that I believed was both correct and efficient.

Roman numerals are a numeral system that originated in ancient Rome, using letters from the Latin alphabet (I, V, X, L, C, D, M) to represent numbers. The system is based on combining letters to indicate the sum or difference of their values, with a few rules:

  • The symbols ‘I’, ‘X’, ‘C’, and ‘M’ can be repeated up to three times in succession to add up their values.
  • When a smaller numeral appears before a larger one, it is subtracted. For example, IV is 4 (5–1), and IX is 9 (10–1).
  • Conversely, when a smaller numeral appears after a larger one, its value is added. For example, VI is 6 (5 + 1).

The provided code snippet is a method named romanToInt that takes a string representing a Roman numeral and converts it into its Arabic numeral equivalent. Here’s a step-by-step explanation:

  • Initialization: It starts with initializing an arabic variable to 0. This will hold the final Arabic numeral value.
  • Loop Through Each Character: The algorithm then iterates through each character in the input Roman numeral string.
  • Switch Statement: For each character, a switch statement is used to match the Roman numeral characters (I, V, X, L, C, D, M). Depending on the character, different actions are taken:
  • Special Cases: For numerals that can be part of a subtractive pair (I, X, C), the algorithm checks the following character. If the pair matches a known subtractive pattern (like IV, IX, XL, XC, CD, CM), it adds the corresponding value to arabic and moves the loop ahead to skip the next character, as it’s already been processed.
  • Regular Cases: For single numerals or those that don’t form a subtractive pair, the algorithm simply adds the numeral’s value to arabic.
  • Accumulation: As the loop progresses, arabic accumulates the total value of the Roman numeral.
  • Return Value: After the loop ends, the method returns the accumulated arabic value, which is the Arabic numeral equivalent of the input Roman numeral.
  • Simplified Example: Consider the Roman numeral “IX”: The loop starts with ‘I’, checks if ‘X’ follows it, recognizes the subtractive pair ‘IX’, and adds 9 to arabic.
    Since both characters have been processed, the loop ends.
    The method returns the value 9.

This algorithm elegantly handles both the additive and subtractive aspects of Roman numerals, converting them to their Arabic counterparts in a straightforward manner. It’s a great example of using basic programming structures to solve a problem rooted in ancient history

My code was as follows:

In my solution, I meticulously handled each Roman numeral, accounting for the complexities of their representation. My code worked perfectly, translating Roman numerals into integers with both correctness and performance. However, the feedback from the interviewer was not what I had expected.

Despite acknowledging the correctness and efficiency of my solution, the interviewer pointed out a critical flaw: my code was not readable. He emphasized that while my solution worked, its lack of readability made it difficult for others to understand and maintain. The interviewer highlighted the importance of writing code that is not only functional but also clear and accessible to other developers. He shared an alternative solution that was more readable and maintainable:

This solution leveraged a map to generalize the conversion process, making the code significantly more readable and easier to understand. The interviewer’s critique resonated deeply with me, imparting a valuable lesson: “Don’t generalize people, generalize the code”!

This experience taught me that the art of coding is not just about solving problems. It’s about crafting solutions that are efficient, but also clear, maintainable, and accessible to others. This lesson has since influenced every line of code I write, reminding me to prioritize readability and maintainability alongside functionality. It was a pivotal moment in my journey as a developer, underscoring the nuanced balance between solving problems and writing good code.

As I shared this story on my blog, my intention was not just to recount a personal experience but to emphasize a universal truth in software development: the code we write is not just for machines to execute, but for humans to understand and build upon. This lesson, learned in the crucible of a coding interview, has been a guiding principle in my development career, reminding me that in the realm of coding, clarity is just as valuable as correctness.

I failed the interview for the Senior Engineer role! What a lesson!

--

--

Aleksandar Danilovic
Javarevisited

Work as Senior Java developer for 16 years. Publish stories about Java, algorithms, object oriented design, system design and programmers' life styles