Interview guides · Aubay Spain
Aubay Spain Software Engineer Interview Guide
Aubay Spain Software Engineer interview guide: the four reported rounds, OOP, SQL, architecture and project questions, and a 7-day prep plan.
The 60-second brief
Aubay Spain is described by candidates as the Spanish arm of an international technology consultancy. Its engineers work on enterprise application systems, modernisation of legacy software and custom platform integrations for clients in banking, telecommunications, insurance and enterprise technology, in Spain and elsewhere in Europe. A Software Engineer works with business unit managers, tech leads and client engineering teams, and the stack follows the project: Java, .NET/C# or Kotlin on the backend, Angular and TypeScript on the frontend, plus enterprise platforms such as Salesforce and SailPoint IdentityIQ, or API architecture work. Reported day-to-day tasks include building microservices and REST APIs, writing SQL queries and stored procedures against SQL Server, MySQL or PostgreSQL, joining design reviews, refactoring legacy code and writing unit and integration tests.
This guide is for candidates applying to Aubay Spain as a Software Engineer, from junior profiles with a strong academic base to mid-level, senior and tech lead profiles, which is the range candidates describe. It covers the four reported rounds, the reported questions on OOP and language mechanics, SQL and persistence, architecture and microservices, project experience and communication, and a 7-day plan. It does not cover the Salesforce or SailPoint specialist tracks in depth.
Candidates report four rounds over roughly 3-5 weeks: HR Screening, Online Technical Assessment, Technical Validation Interview and Client-Specific Interview. The last stage is reported as depending on the client placement.
Focus areas
- Coding tests / programming quizzes
- Technical interviews
- Recruiter screening (HR interview)
Overview
Aubay Spain is a consultancy, so the job is shaped by whichever client project you are matched to, and the language and framework change with it. Candidates list Java, .NET/C#, Kotlin, Python, C and TypeScript/Angular as the languages that come up. Pick one primary language you can write fluently under a timer and be ready to say so plainly during the first call, because candidates report that stating your technical preferences early helps the recruiter match you to an opportunity.
The reported questions fall into five families. Core OOP and language mechanics covers the four OOP principles, abstract classes versus interfaces, access modifiers, how references and memory allocation work in Java or .NET, and binary representation with bitwise operations. Databases covers joins, indexes and B-trees, primary and foreign keys, ACID and isolation levels, and a GROUP BY / HAVING / subquery query. Architecture covers design patterns, REST, monolith versus microservices, cross-cutting concerns and data consistency across services. The last two families are project history and communication. Candidates describe the online assessment as logic, OOP, algorithm and database questions, so the first two families are the ones to rehearse under a clock.
Seniority changes how you should spend your time. Candidates describe positions from junior (0-2 years, academic foundations) up to senior and tech lead (3-8+ years, architecture ownership). A junior profile gains most from precise, example-backed answers on OOP, SQL and one language runtime. A senior profile also needs two or three project stories in which you made and defended architectural decisions, since the technical validation stage is reported to revolve around past projects and assessment results.
Language and client readiness are part of the loop as candidates describe it: an English self-introduction at the recruiter stage, an English assessment alongside discussions in Spanish, and a possible final conversation with someone from the client. Practise explaining a trade-off, such as monolith versus microservices or why you chose an index, in both languages. If cloud (AWS, Azure), CI/CD, automated testing, Salesforce or SailPoint IdentityIQ appears on your CV, expect to be asked about it, since candidates list these as nice-to-have experience.
The Aubay Spain interview process
Candidates report these four stages in this order over roughly 3-5 weeks. Whether you reach the final client stage depends on the project you are being matched to.
HR Screening
Candidates describe a conversational call with a recruiter that covers your career history, familiarity with the tech stack, salary expectations and a short check of your spoken English. One report says it checks your programming preferences rather than asking you to code. The practical goal is to leave the recruiter with a clear picture of which languages and project types fit you, so be specific: name your primary language, the frameworks you have shipped with, and the kinds of client work you want.
What to demonstrate
- Career history, academic training and the projects you have worked on
- Familiarity with the tech stack and stated language preferences
- Spoken English, through a short self-introduction
- Salary expectations as they relate to the opportunity
How to prepare
- Write and rehearse an English self-introduction that names your primary language, one or two frameworks, and one project outcome, then say the Spanish version too.
- State your preferred language and the stacks you would accept before the call, so you can answer without hedging.
- Prepare an answer on where you want to be in two to three years and which technical domains you want to master.
- Decide your salary expectations and notice period in advance, and ask what the next stages involve.
Online Technical Assessment
This is an automated test on a platform such as CodinGame or HackerRank, or a custom timed quiz. Candidates report logic problems, object-oriented concepts, algorithm challenges and database queries, with per-question time limits. Because the stage is timed and automated, the skill is reading the constraints carefully, choosing a simple correct approach, and finishing working code in the language you are strongest in.
What to demonstrate
- Working code under the platform's time limits
- Logic and algorithm problem solving
- OOP concepts and language syntax
- Writing correct SQL queries
How to prepare
- Do timed practice on CodinGame-style and HackerRank-style problems in your primary language, and read every constraint before you write code.
- Drill fast answers on access modifiers, inheritance, interfaces versus abstract classes and what happens on the stack and the heap.
- Practise SQL that combines joins, GROUP BY, HAVING and a subquery, and check your result against edge cases such as empty groups and NULLs.
- Revisit binary representation and bitwise operators (AND, OR, XOR, shifts) so bit-level logic does not cost you time.
Technical Validation Interview
Candidates describe an interview with a Tech Lead or Engineering Manager, and in other reports a business unit director, that revisits your assessment results and goes through past projects. Reported topics are framework architecture, system design principles, microservices and how you implemented things in earlier work. Come ready to explain why your answers in the assessment were right, to correct any that were not, and to defend design decisions from your own projects with trade-offs.
What to demonstrate
- How you explain and correct your own online assessment answers
- Depth in framework architecture, system design principles and microservices
- Ownership of decisions in past projects
- Clarity when explaining technical reasoning aloud
How to prepare
- Re-solve your assessment problems afterwards so you can explain the approach and its complexity, and any mistake you made.
- Prepare a diagram and a short narrative of one complex project: your role, the stack, the data model and two architectural decisions with alternatives you rejected.
- Prepare the monolith-to-microservices trade-off, service boundaries, an API gateway, centralised configuration and asynchronous messaging, with a concrete example of each.
- Rehearse a production bug or performance story with the exact diagnostic steps, and a short account of how you apply dependency injection in your framework.
Client-Specific Interview
Candidates describe a final interview, depending on the placement, with a stakeholder from the client, to confirm that you and the specific project are a good match. It follows the internal technical stages, so the emphasis shifts from fundamentals to communication, project context and expectations on both sides. Prepare to describe your experience in terms of the client's domain and to ask good questions about the engagement.
What to demonstrate
- Fit between your experience and the specific client project
- Communication with client-side technical or business contacts
- Adaptability to existing codebases and established team workflows
How to prepare
- Use what the recruiter told you about the client's sector (banking, telecom, insurance or enterprise technology) to prepare two relevant examples from your experience.
- Prepare to explain a technical trade-off in plain language to a non-technical manager, in English and in Spanish.
- Have your answer ready on changing scope or ambiguous requirements raised by client management, with a concrete story.
- Prepare questions about project setup, team structure, the client's domain and hybrid or remote arrangements.
Where candidates lose points
Defining abstract class versus interface from memory with no deciding example
Give the contrast in your language. Java and C# classes extend one base class but implement many interfaces, and an interface defines a contract while an abstract class can hold shared state and partial behaviour. Then name a situation where you chose each, and mention that default interface methods blur the line.
Rushing a timed CodinGame or HackerRank test and missing a constraint or edge case
Read the statement and limits fully, run the sample cases, then test an empty input, a single element and the largest size before moving on. Write a simple correct solution first and tune it only if time remains.
Writing SQL that gives plausible but wrong numbers, such as filtering an aggregate in WHERE or turning a LEFT JOIN into an inner join
Use WHERE for row filters and HAVING for filters on aggregates. Put conditions on the optional side of a LEFT JOIN in the ON clause, and check for one-to-many joins before summing. Explain the same query with EXPLAIN and say which index it uses.
Walking through a project as a list of technologies with none of your own decisions
Prepare a story for one project with your role, the data model, two decisions you made and what you rejected, and one failure with its fix. Be ready to defend each choice in the architecture discussion of the technical validation interview.
Answering monolith versus microservices as if microservices are always the better option
Talk about the costs as well as the benefits: network calls, distributed data consistency, deployment and monitoring overhead, and when a monolith with clean modules is enough. Tie it to a legacy modernisation example, since modernising legacy systems is a reported part of the work.
Questions & practice
Explain the core principles of Object-Oriented Programming (OOP) and give practical examples of encapsulation,
Medium · Core Object-Oriented Programming & Langu
Explain the core principles of Object-Oriented Programming (OOP) and give practical examples of encapsulation, inheritance, polymorphism, and abstraction.
Approach
- Encapsulation: keep state private and let methods enforce its rules, e.g. an Account whose private balance changes only through withdraw(), which rejects an overdraft; a getter for an internal list returns an unmodifiable view, not the list itself.
- Inheritance: use it for a true is-a relationship (SavingsAccount extends Account) and state the Liskov rule: a subclass must work wherever the parent is expected. Name the cost (fragile base class) and when you would use composition instead.
- Polymorphism: separate compile-time overloading (resolved by the argument types) from runtime overriding (dynamic dispatch on the object's actual type), e.g. looping over a List<PaymentMethod> and calling pay() on each.
- Abstraction: callers depend on what a component does, not how, e.g. a Notifier interface with Email and SMS implementations, so the calling code never changes when a channel is added.
Follow-up
- Give an example where you would replace inheritance with composition, and say why.
- Show a Liskov violation (the Square extends Rectangle case) and how you would fix it.
- How does the compiler pick between two overloads when one takes int and the other takes long or Integer?
How do access modifiers (public, private, protected, default) enforce data hiding and encapsulation?
Medium · Core Object-Oriented Programming & Langu
Approach
- List the Java levels precisely: private (the class only), package-private by default (same package), protected (same package plus subclasses), public. Note that Java protected is wider than people expect because it includes package access.
- Give the C# set as well, if C# is your language: private (the default for class members), protected, internal (same assembly, the default for top-level types), protected internal, private protected, public.
- Explain how this hides data: when the fields are private, only the class's own methods can write them, so a validated setter or constructor keeps the invariant true for every caller.
- Name the leak that private does not stop: returning a reference to an internal mutable collection or Date lets callers change state. Return List.copyOf or an unmodifiable view, or a defensive copy.
- Access modifiers are a compile-time design boundary, not a security boundary: reflection can bypass them, though the Java module system (strongly encapsulated JDK internals since Java 16/17) restricts that.
Follow-up
- Can an overriding method in Java reduce the visibility of the method it overrides? Can it widen it?
- What are private constructors used for?
- Can an outer class read a private field of its nested class in Java?
Explain how object reference and memory allocation operate under the hood in managed runtime environments like
Medium · Core Object-Oriented Programming & Langu
Explain how object reference and memory allocation operate under the hood in managed runtime environments like Java or.NET.
Approach
- Separate the stack and the heap: each thread's stack frames hold local variables, primitives and references; objects created with new live on the heap. In C#, struct values are stored inline (in the frame or inside their containing object), while class instances go on the heap.
- Explain passing: Java passes everything by value, including the reference, so reassigning a parameter does not affect the caller but mutating the object does. C# adds ref/out for real pass-by-reference.
- Describe allocation and collection: HotSpot allocates by bumping a pointer in a thread-local allocation buffer, which is why allocation is cheap. The GC finds live objects by reachability from roots (stack references, static fields), and generational collectors sweep the young generation often and promote survivors. .NET uses generations 0/1/2 plus a Large Object Heap for objects of 85,000 bytes or more.
- Mention JIT details as a bonus: escape analysis can remove an allocation for an object that never leaves a method.
- Leaks still happen in managed runtimes: static collections that only grow, listeners never removed, caches without eviction. You find them with a heap dump (jcmd GC.heap_dump, dotnet-gcdump) and by looking at what retains the objects.
Follow-up
- Why can Integer a = 127, b = 127 compare equal with == while 128 does not?
- What is the difference between a StackOverflowError and an OutOfMemoryError, and what causes each?
- How do try-with-resources or IDisposable relate to garbage collection?
What are standard binary number representations, and how do low-level bitwise operations work in foundational
Medium · Core Object-Oriented Programming & Langu
What are standard binary number representations, and how do low-level bitwise operations work in foundational programming algorithms?
Approach
- Representation: signed integers use two's complement, so -x equals ~x + 1 and an n-bit type covers -2^(n-1) to 2^(n-1)-1. Java int arithmetic overflows silently (Math.addExact throws). Floats follow IEEE 754 (sign, exponent, mantissa), which is why 0.1 + 0.2 != 0.3.
- Operators: & | ^ ~ <<, and the two right shifts. Java's >> extends the sign and >>> fills with zeros; in C#, >> on int is arithmetic and on uint is logical, and C# 11 added >>>.
- Idioms worth writing from memory: x & 1 for parity; x & (x - 1) clears the lowest set bit, so x > 0 && (x & (x - 1)) == 0 tests for a power of two; x & -x isolates the lowest set bit; Kernighan's popcount loop runs once per set bit.
- Algorithmic uses: XOR every element to find the single unpaired number in O(n) time and O(1) space; enumerate all subsets of n items as the bitmasks 0 to 2^n - 1; pack boolean flags or permissions into one int.
- Edge cases: Java masks an int shift distance to 5 bits, so 1 << 32 == 1; -Integer.MIN_VALUE and Math.abs(Integer.MIN_VALUE) both return Integer.MIN_VALUE.
Follow-up
- Count the set bits of every number from 0 to n in O(n). (bits[i] = bits[i >> 1] + (i & 1))
- Swap two variables with XOR. Why does it fail if both refer to the same memory location?
- How would you store and check a set of user permissions as bit flags?
How do database transactions guarantee ACID properties, and how do isolation levels mitigate concurrency issue
Medium · Databases & SQL Persistence
How do database transactions guarantee ACID properties, and how do isolation levels mitigate concurrency issues?
Approach
- Map each letter to a mechanism. Atomicity: the undo/write-ahead log lets a failed transaction roll back completely. Consistency: constraints hold at commit. Isolation: locking (two-phase locking) or MVCC snapshots. Durability: the commit is acknowledged only after the log is flushed to disk.
- Name the anomalies in order: dirty read, non-repeatable read, phantom read, plus lost update and write skew, which the standard levels do not spell out.
- The levels: Read Uncommitted, Read Committed, Repeatable Read, Serializable. Know the defaults: Read Committed in PostgreSQL and SQL Server, Repeatable Read in MySQL InnoDB. PostgreSQL's Repeatable Read is snapshot isolation and also prevents phantoms, and its Read Uncommitted behaves like Read Committed.
- Fixing a lost update without going to Serializable: an atomic UPDATE stock SET qty = qty - 1 WHERE id = ? AND qty > 0, SELECT ... FOR UPDATE, or optimistic locking with a version column (JPA @Version) that fails if the row changed.
- The trade-off: higher isolation means more blocking or more aborted transactions (serialization failures), so the application needs a retry loop and short transactions.
Follow-up
- Describe write skew (two on-call doctors both going off call) and the isolation level that prevents it.
- How does the database detect and resolve a deadlock, and what do you do in the application?
- With a framework-managed transaction such as Spring's @Transactional, why does calling the annotated method from the same class skip the transaction?
How do inner, outer, left, and right SQL joins differ, and how do query execution plans handle large dataset c
Medium · Databases & SQL Persistence
How do inner, outer, left, and right SQL joins differ, and how do query execution plans handle large dataset combinations?
Approach
- Define each join by its unmatched rows: INNER keeps matches only; LEFT keeps every left row and pads the right side with NULLs; RIGHT is the mirror; FULL OUTER keeps both sides' unmatched rows. MySQL has no FULL OUTER JOIN: emulate it with a LEFT JOIN UNION ALL a RIGHT JOIN filtered to rows whose left key IS NULL.
- Name the classic trap: a WHERE condition on the right table of a LEFT JOIN removes the NULL-padded rows and silently turns it into an inner join. Put that condition in the ON clause. Also check whether the join is one-to-many, because it multiplies rows before any SUM.
- Physical join algorithms: nested loop (good when the outer side is small and the inner side has an index on the join key), hash join (build a hash table on the smaller input, then probe; about O(n + m), equality joins only, needs memory), merge join (both inputs sorted on the key). MySQL gained hash joins in 8.0.18.
- Reading a plan: run EXPLAIN / EXPLAIN ANALYZE (PostgreSQL, MySQL 8.0.18+) or the actual execution plan in SQL Server, compare estimated and actual row counts, and suspect stale statistics when they differ widely (ANALYZE, UPDATE STATISTICS).
Follow-up
- Find customers with no orders. Compare LEFT JOIN ... IS NULL, NOT EXISTS and NOT IN, and say what NOT IN does when the subquery returns a NULL.
- Why might the optimizer pick a nested loop over two large tables, and how would you check whether that was right?
- How do you join three tables when one link is many-to-many without double counting?
Write a query to aggregate and filter data using GROUP BY, HAVING, and nested subqueries.
Medium · Databases & SQL Persistence
Approach
- Write a concrete example: SELECT customer_id, SUM(amount) AS total FROM orders WHERE order_date >= '2024-01-01' AND order_date < '2025-01-01' GROUP BY customer_id HAVING SUM(amount) > (SELECT AVG(t) FROM (SELECT SUM(amount) AS t FROM orders WHERE ... GROUP BY customer_id) x). Customers above the average customer total.
- State the logical order: FROM/JOIN, WHERE, GROUP BY, HAVING, SELECT, ORDER BY, LIMIT. WHERE filters rows before grouping and can use an index; HAVING filters groups; an aggregate inside WHERE is an error. MySQL accepts a SELECT alias in HAVING, PostgreSQL and SQL Server do not.
- Every non-aggregated column in SELECT must appear in GROUP BY (MySQL enforces this with ONLY_FULL_GROUP_BY, on by default since 5.7).
- NULL handling: COUNT(*) counts rows, COUNT(col) skips NULLs, AVG ignores NULLs, and SUM over zero rows returns NULL, so wrap it in COALESCE. Use a half-open date range rather than YEAR(order_date) = 2024 so an index on the date stays usable.
- For top-N per group, use a CTE with ROW_NUMBER() (or RANK/DENSE_RANK for ties) OVER (PARTITION BY ... ORDER BY ...), or a correlated subquery. Rewrite a per-row correlated subquery in SELECT as a join to a pre-aggregated derived table when it is slow.
Follow-up
- Return the top three products by revenue in each category, including ties.
- Revenue doubles after you join order_items. Why, and how do you fix it?
- Rewrite the nested subquery as a CTE. Does that change performance?
What is the difference between abstract classes and interfaces, and when would you choose one over the other i
Medium · Core Object-Oriented Programming & Langu
What is the difference between abstract classes and interfaces, and when would you choose one over the other in software architecture?
Approach
- An abstract class can hold instance fields, constructors, any access level and partly written methods; a class extends only one class in both Java and C#.
- An interface is a contract a class can implement many times over. Java 8 added default and static methods and Java 9 private ones, C# 8 added default interface methods, but neither allows instance state (Java interface fields are implicitly public static final).
- Choose an interface for a capability shared by unrelated types (Comparable, IDisposable) and for anything you inject or mock. Choose an abstract class when closely related types share state and a fixed algorithm (template method).
- Name the evolution trade-off: adding an abstract method breaks every subclass, while a default method lets an interface grow. If two interfaces supply the same default method, the class must override it to resolve the conflict.
- A common combination: an interface for callers plus an abstract skeleton for implementers, as in Java's List and AbstractList.
Follow-up
- A class implements two interfaces that both define the same default method. What happens and how do you fix it?
- Can an abstract class have a constructor, and when does it run?
- In a modular application, which of the two would you expose across module boundaries, and why?
What are database indexes, how are B-tree indexes structured, and what impact do they have on read versus writ
Medium · Databases & SQL Persistence
What are database indexes, how are B-tree indexes structured, and what impact do they have on read versus write performance?
Approach
- Structure: a B+tree is balanced and has a high fanout. Internal nodes hold keys and child pointers; the leaves hold sorted keys with row pointers (or the rows themselves in a clustered index) and are linked for range scans. A lookup is O(log N), and a few levels cover millions of rows.
- Clustered and secondary: InnoDB stores the table in primary-key order, and its secondary index leaves hold the primary key, so a lookup goes through two indexes. SQL Server has an optional clustered index. PostgreSQL keeps a heap and points at it from every index. A covering index (or INCLUDE columns in PostgreSQL 11+ and SQL Server) avoids the second lookup.
- Reads it speeds up: equality, ranges, ORDER BY and joins on the key. For a composite index (a, b), the leftmost-prefix rule applies: it helps WHERE a = ? and WHERE a = ? AND b > ?, not WHERE b = ?. Applying a function to the column (YEAR(created_at) = 2024), a LIKE pattern starting with %, or an implicit type conversion makes the index unusable.
- Write cost: every INSERT, DELETE and UPDATE of an indexed column maintains every index, causing page splits, more I/O and more pressure on the buffer pool. Random UUID primary keys fragment a clustered index, while sequential keys append. Indexes on low-selectivity columns are often ignored.
Follow-up
- The optimizer ignores your index. What are the possible reasons and how do you check?
- Auto-increment versus UUID primary keys in InnoDB: what is the write-performance difference?
- When would a hash index beat a B-tree, and what can it not do?
Explain primary key and foreign key constraints and how foreign keys maintain referential integrity.
Medium · Databases & SQL Persistence
Approach
- Primary key: unique and NOT NULL, one per table, possibly composite, and enforced through a unique index (clustered by default in InnoDB and SQL Server). Give the trade-off between surrogate and natural keys: a stable meaningless id versus a business value that may change.
- Foreign key: a child column that references a primary or unique key in the parent. The database rejects a child row whose value has no parent (unless the column is NULL) and checks deletes and key updates on the parent.
- Referential actions: ON DELETE / ON UPDATE CASCADE, SET NULL, SET DEFAULT, RESTRICT, NO ACTION. In PostgreSQL a constraint declared DEFERRABLE INITIALLY DEFERRED is checked at commit, which lets you insert rows that reference each other in a cycle.
- Index the child's foreign-key column: PostgreSQL does not create that index for you (InnoDB requires one and creates it), and without it every parent delete scans the child table and holds locks longer.
- Edge case: under the default MATCH SIMPLE, a composite foreign key with any NULL column is not checked at all.
Follow-up
- When would you leave foreign keys out, for example across microservice databases or during bulk loads, and what replaces them?
- Cascade delete or soft delete for orders that belong to a closed customer account?
- How do you insert two rows that reference each other?
Describe common design patterns (e.g., Singleton, Factory, Dependency Injection, Observer) and describe a scen
Medium · Software Architecture & Microservices
Describe common design patterns (e.g., Singleton, Factory, Dependency Injection, Observer) and describe a scenario where you implemented one.
Approach
- Singleton: one shared instance. In Java, write it as an enum or with the holder-class idiom; in C#, as Lazy<T>. Name the downsides (hidden global state, hard to test) and the usual alternative: a singleton-scoped bean registered in the DI container.
- Factory: one place decides which implementation to build, e.g. a factory that returns the right PaymentProcessor by country. A map of constructors or suppliers keeps it open for extension instead of a growing switch.
- Dependency Injection: dependencies arrive through the constructor and a container wires them (Spring, ASP.NET Core's built-in container, Angular's injector). Know the lifetimes (singleton, scoped, transient) and the captive-dependency bug where a singleton holds a scoped service.
- Observer: a subject notifies its subscribers (Java listeners, C# events, RxJS in Angular). Pitfalls: leaks when subscribers never unsubscribe, and one subscriber's exception or slowness blocking the others in synchronous notification.
- For the scenario, tell it briefly: the duplication or coupling you had, the pattern you applied, what got simpler (for example, adding a provider without editing callers), and a case where you chose not to use the pattern.
Follow-up
- Write a thread-safe lazy singleton with double-checked locking. Why must the field be volatile?
- What is the difference between Strategy and Factory?
- How does constructor injection make a class easier to unit test?
How do RESTful APIs manage state, and what best practices do you follow when designing scalable API endpoints?
Medium · Software Architecture & Microservices
Approach
- Statelessness: each request carries what the server needs (a bearer token or a session id checked against a shared store), and no instance keeps per-client memory, so any instance behind the load balancer can serve any request. Resource state lives in the database and travels as representations.
- Resource design: plural nouns and nesting where ownership is real (/orders/{id}/items). Method semantics: GET is safe and idempotent, PUT replaces and is idempotent, PATCH updates part of a resource, POST creates and is not idempotent, DELETE is idempotent.
- Status codes and errors: 201 with a Location header, 204, 400 or 422 for validation, 401 versus 403, 404, 409 for conflicts, 429 for rate limits, and one error body format such as RFC 9457 problem details.
- Scaling the endpoints: cursor pagination (OFFSET slows down on deep pages), filtering, caching with Cache-Control and ETag / If-None-Match returning 304, idempotency keys so a retried POST does not create a duplicate, and rate limiting.
- Evolving the contract: version in the path or a header, prefer additive backward-compatible changes, and use ETag with If-Match (412 on mismatch) for optimistic concurrency on updates.
Follow-up
- A client times out on POST /payments and retries. How do you make sure it is charged once?
- When do you choose PUT over PATCH?
- How do you revoke a JWT before it expires?
What are the core architectural differences between a monolithic application and a microservices-based archite
Medium · Software Architecture & Microservices
What are the core architectural differences between a monolithic application and a microservices-based architecture?
Approach
- Monolith: one deployable and usually one database. In-process calls, local ACID transactions and simple debugging. Costs: the whole application redeploys for any change, everything scales together, and coupling grows unless modules are enforced.
- Microservices: independently deployable services split by business capability, each owning its data, talking over HTTP/gRPC or messaging. Gains: independent deployment and scaling, per-service technology choices, team autonomy.
- Name what microservices cost: network latency and partial failure, no cross-service ACID transactions (eventual consistency instead), distributed tracing, and a CI/CD pipeline, service discovery and gateway to operate.
- Give a decision rule: a modular monolith first for a small team or unclear domain boundaries; extract services where deploy cadence, scaling or ownership really differ. Warn against the distributed monolith: a shared database, chatty synchronous chains, lockstep releases.
- Migration from legacy: the strangler fig pattern. Route one bounded context at a time through a gateway to a new service, add an anti-corruption layer, and split the shared database last and carefully.
Follow-up
- Which part of a legacy monolith would you extract first, and why?
- A report used to join tables that now belong to two services. How do you serve it?
- How do you split a shared database without downtime?
How do you handle cross-cutting concerns such as logging, authentication, and error handling in scalable micro
Medium · Software Architecture & Microservices
How do you handle cross-cutting concerns such as logging, authentication, and error handling in scalable microservices?
Approach
- Logging and tracing: structured (JSON) logs with a correlation id passed between services in headers (W3C traceparent), central aggregation, and distributed tracing with OpenTelemetry so one request can be followed across services. Never log tokens, passwords or personal data.
- Authentication: the gateway checks the OAuth2/OIDC token (signature via JWKS, expiry, audience), and each service still checks the scopes it needs rather than trusting the network. Service-to-service calls use mTLS or client-credentials tokens.
- Error handling: map exceptions to one error contract in a central handler (Spring @ControllerAdvice, ASP.NET Core exception middleware). Every remote call gets a timeout, retries with exponential backoff and jitter only for idempotent calls, and a circuit breaker (Resilience4j, Polly).
- Where the logic lives: gateway, shared library or middleware, or a sidecar/service mesh. A shared library ties services to one version; a mesh adds operational complexity. Pick per concern.
- Close with observability: request rate, error and duration metrics per service, plus liveness and readiness endpoints.
Follow-up
- One request across five services is slow. How do you find which hop is responsible?
- How do retries cause a retry storm, and how do you prevent it?
- How do you pass the end user's identity to a downstream service?
What mechanisms do you use to maintain data consistency across distributed services or asynchronous message br
Medium · Software Architecture & Microservices
What mechanisms do you use to maintain data consistency across distributed services or asynchronous message brokers?
Approach
- Start from the problem: once each service has its own database, there is no single transaction across them. Two-phase commit (XA) exists but blocks on its coordinator and fits brokers poorly, so most designs accept eventual consistency.
- Saga: a chain of local transactions with compensating actions (refund the payment, release the stock) when a later step fails. Orchestration uses a central coordinator; choreography uses events. Compensation is a business reversal, not a rollback, and the intermediate states are visible.
- Transactional outbox: write the business row and an outbox event in the same local transaction, then a relay (polling, or change data capture such as Debezium) publishes it. This removes the dual-write bug where the database commits but the message is lost.
- Consumers must be idempotent because brokers usually deliver at least once: record processed message ids or use upserts. Ordering is guaranteed only within a partition (in Kafka, per partition key).
- Back it up with reconciliation jobs that detect drift, and with version numbers or optimistic locking on entities updated by several flows.
Follow-up
- A consumer writes to its database and crashes before acknowledging the message. What happens next, and is the result correct?
- Two events for the same order arrive out of order. How do you handle it?
- When is two-phase commit an acceptable choice?
Walk us through a complex project from your past experience: what was your role, what technical stack was used
Medium · Professional Background & Technical Port
Walk us through a complex project from your past experience: what was your role, what technical stack was used, and what architectural decisions did you make?
Approach
- Structure the answer: the business problem and its scale in numbers, your exact role (what you did versus the team), the stack, two or three architecture decisions, the measurable outcome, and what you would change.
- For each decision, give the alternative you rejected and why, e.g. PostgreSQL over a document store for referential integrity, or a message queue over synchronous REST to absorb load spikes.
- Be ready to describe the system diagram in words: the components, how a request flows through them, and the core tables of the schema.
- Only name technologies you can explain under questioning; every component you mention can become the next question.
- Say "I" for your work and "the team" for theirs; blurring the two makes your role impossible to judge.
Follow-up
- What would break first if the load grew tenfold?
- Which decision would you reverse with what you know now?
- What was the hardest bug on that project?
Describe a challenging bug or performance bottleneck you encountered in production and detail the exact steps
Medium · Professional Background & Technical Port
Describe a challenging bug or performance bottleneck you encountered in production and detail the exact steps you took to diagnose and resolve it.
Approach
- Tell it as a debugging sequence: the symptom with a number (p95 latency, error rate, memory growth), the blast radius, reproduction, hypotheses, the measurement that confirmed one, the fix, verification against the same number, and the prevention.
- Name the tools you actually used: APM traces, EXPLAIN ANALYZE, a profiler, thread dumps for lock contention, heap dumps and GC logs for memory, connection-pool metrics.
- Typical root causes worth recognising: an ORM N+1 query fixed with a fetch join or batch loading, a missing or unusable index, an exhausted connection pool, an unbounded static cache.
- Separate mitigation from fix: if production was hurting, say what you did first (rollback, feature flag, scaling out) before finding the root cause.
- Mention the hypotheses you ruled out and how; that shows the diagnosis was evidence-based rather than lucky.
Follow-up
- How did you confirm the fix worked in production?
- What alert or test did you add so it cannot come back unnoticed?
- What would you have done if you could not reproduce it locally?
How do you select specific libraries, frameworks, or tools when starting a new software project or feature?
Medium · Professional Background & Technical Port
Approach
- Start from constraints: the requirement, the existing stack and runtime version (Java LTS, .NET version, Angular version), the licence (GPL versus MIT/Apache in proprietary client code), and any security policy.
- Assess health: release activity, open issues, the number of maintainers, documentation quality, known CVEs (OWASP Dependency-Check, npm audit) and how heavy its transitive dependencies are.
- Prove it cheaply: a timeboxed spike against agreed acceptance criteria (performance, ergonomics, testability), then record the choice and the rejected options in an architecture decision record.
- Prefer the standard library or tooling the team already runs over a new dependency, and wrap a new library behind your own interface so it can be replaced.
- Close with a real example: what you chose, what you rejected and why.
Follow-up
- Tell me about a library choice that turned out wrong. What did it cost to replace?
- A transitive dependency has a critical CVE and no patched release. What do you do?
- The client mandates a tool you think is worse. How do you handle it?
Tell us about an academic or professional project where you had to quickly master an unfamiliar technology or
Medium · Professional Background & Technical Port
Tell us about an academic or professional project where you had to quickly master an unfamiliar technology or framework.
Approach
- Choose a real case with a deadline and a concrete deliverable, so the result can be judged.
- Describe the learning method: official docs and the core concepts first, a small throwaway prototype, reading the existing codebase, pairing with someone experienced, and mapping new ideas onto ones you know (e.g. Angular's dependency injection versus Spring's).
- Show a mistake you made while learning and how you caught it (a code review, a failing test, a profiler).
- State what you shipped and how you passed the knowledge on (notes, a README, a short session for the team).
Follow-up
- How did you know you understood it well enough to ship production code?
- How would you get productive on an unfamiliar legacy codebase in your first week?
- What are you learning now, and how?
How do you balance code quality and refactoring against tight delivery deadlines?
Medium · Professional Background & Technical Port
Approach
- Separate what you never cut (tests for changed logic, security, backward-compatible contracts) from what can wait (refactoring adjacent code, broader cleanup).
- Make the debt visible: a ticket with its cost and risk, agreed with the tech lead or client, rather than a silent shortcut.
- Refactor before a change when that lowers the risk of the change itself. On legacy code, write characterization tests first so the refactor has a safety net.
- Give one concrete story: the deadline, the shortcut you accepted, the safeguard you kept, and when and how the debt was repaid.
- Avoid both extremes: "I never compromise" sounds unrealistic and "I just ship" sounds careless.
Follow-up
- When would you refuse to ship on time?
- How would you convince a manager or client to fund a refactoring?
- How do you measure whether technical debt is getting worse?
Please introduce yourself and summarize your software development background in English.
Medium · Communication & Multilingual Competency
Approach
- Use a present, past, future structure and keep it short: current role and main stack, one or two projects with one concrete result each, then why client-project engineering interests you now.
- Rehearse aloud in English and record yourself. Know the English names for your stack and practices (dependency injection, unit tests, pull request, deployment). Candidates report discussions in Spanish as well, so prepare both versions.
- Lead with the stack and domain that fit the roles you want, since candidates report the screening covers stack familiarity.
- Avoid reciting your CV in date order or a memorised monotone. If a word escapes you, paraphrase and keep going.
Follow-up
- Describe the architecture of your last project in English.
- Why are you looking to move now?
- Which client sectors or project types interest you most?
How do you communicate complex technical decisions or trade-offs to non-technical business stakeholders?
Medium · Communication & Multilingual Competency
Approach
- Translate into business terms: cost, delivery date, risk and user impact, not frameworks or patterns.
- Present two or three options with their consequences, then a clear recommendation and the reason for it.
- Use a diagram or a short analogy when it helps, check understanding by asking the stakeholder to restate the decision, and confirm it in writing.
- Tell one real example: the trade-off, how you framed it, what was decided, and how it turned out.
- Avoid jargon and avoid presenting options without a recommendation; both push the decision back onto someone who cannot weigh it.
Follow-up
- The stakeholder rejects your recommendation. What do you do?
- How would you explain technical debt to a project manager?
- Explain to a non-technical client why moving to microservices slows feature delivery at first.
What are your career development goals for the next two to three years, and what technical domains do you want
Medium · Communication & Multilingual Competency
What are your career development goals for the next two to three years, and what technical domains do you want to master?
Approach
- Be concrete: name the technical domains you want to deepen, picked honestly from work this role covers (backend Java or .NET, Angular, cloud platforms such as AWS or Azure, microservices), and any move toward tech lead or architecture work if you want it.
- Show a plan already in motion: a certification, a side project, a course, or responsibilities you have taken on recently.
- Connect the goal to the job: say how working on different client projects would help you reach it, without claiming anything about the company you have not been told.
- Avoid vague answers ("keep growing") and goals that suggest you will leave soon. Match the ambition to your experience level.
Follow-up
- What have you done in the last year toward that goal?
- Would you accept a project on a stack outside the domains you named?
- What would you do if a tech lead track were not available?
Every query on one table stalls for forty seconds mid-deploy
Medium · lock contention · ddl · migrations
During a release on PostgreSQL, every query touching resource times out for about 40 seconds and then recovers with no intervention. The release ran one migration, ALTER TABLE resource ADD COLUMN archived_reason TEXT, and the migration log shows it completing in 6 ms. Unrelated tables showed no change in error rate. Explain how a 6 ms statement caused a 40-second stall, give the ordered checks you would run on a live system to confirm it, and give the migration procedure that prevents a repeat.
Approach
- Separate the statement's duration from the lock's duration. ADD COLUMN with no default is a catalogue-only change and genuinely runs in milliseconds, but it requires ACCESS EXCLUSIVE, and it cannot acquire that until every transaction already touching the table has finished.
- Account for the queueing, which is the part that surprises people. A lock request that is waiting blocks later requests for conflicting modes behind it rather than letting them overtake, so one long-open transaction holds the DDL and the DDL holds all the traffic. The stall length is set by the longest open transaction, not by the size of the change.
- Confirm on a live system in this order: pg_stat_activity for that table ordered by xact_start, looking for the oldest transaction and specifically for state = idle in transaction; then pg_locks where granted = false to find the waiter; then join them on pid to name blocker and blocked. pg_blocking_pids() does that join for you and is the fastest single call.
- Prevent rather than merely time it better. Set lock_timeout to a second or two on the migration session so the DDL abandons the queue after a bounded wait and is retried, instead of holding it for as long as the oldest transaction lives. Be exact about what that buys: queries arriving during the wait still queue behind the pending ACCESS EXCLUSIVE request, so each attempt costs them up to one lock_timeout of added latency. The outage goes from 40 seconds to about one second per attempt, not to zero. Also run migrations away from deploy-time peaks, and put a statement timeout and an idle-in-transaction timeout on the analytics role that opens the long transactions.
Follow-up
- The same release also wants NOT NULL on that column. What is the sequence that gets there without a long lock?
- Your lock_timeout retry fails ten times in a row because the analytics transaction is always open. What do you change?
Suggested practice checklist
The plan follows the four reported rounds and the five question families candidates report: OOP and language mechanics, SQL, architecture, project stories and communication. Days 2 to 4 build technical fluency under a clock, and days 5 to 7 prepare the discussion rounds and the client stage.
Day 1 — Recruiter call and bilingual introduction
- Write your English self-introduction (background, primary language, one project outcome) and record yourself saying it, then repeat in Spanish.
- Write a short answer on your career goals for the next two to three years and the technical domains you want to master.
- List your primary language, other languages you can use, and the project types you prefer, plus your salary expectations and notice period.
Deliverable: A written and recorded English introduction, a Spanish version, a career-goals answer and a one-page stack and preference sheet for the recruiter call.
Day 2 — OOP and language mechanics
- Write a short Java or C# example that shows encapsulation, inheritance, polymorphism and abstraction in one small domain, such as payments or accounts.
- Write an abstract class and an interface for the same problem, and decide in one paragraph which you would choose and why.
- Explain access modifiers and how references, the stack and the heap work for an object in Java or .NET, and where garbage collection fits in.
- Practise binary representation (two's complement) and write small bitwise exercises: check a bit, count set bits, swap with XOR.
Deliverable: One code example covering the four OOP principles, an abstract-versus-interface decision note, a written explanation of references and memory, and a worked set of bitwise exercises.
Day 3 — SQL and relational persistence
- Build a small schema with primary and foreign keys in PostgreSQL or MySQL and write inner, left and full outer join queries over it, noting which rows each one keeps.
- Write one query that uses GROUP BY, HAVING and a nested subquery, then rewrite it with a CTE or a join.
- Run EXPLAIN before and after adding an index, and write down what changed, how a B-tree index is structured and what it costs on writes.
- Write out ACID and each isolation level with the anomaly it prevents (dirty read, non-repeatable read, phantom).
Deliverable: A schema with working join and aggregate queries, a before-and-after EXPLAIN comparison, and a one-page ACID and isolation-level sheet.
Day 4 — Timed assessment simulation
- Run a timed session on CodinGame-style or HackerRank-style practice in your primary language, reading all constraints before coding.
- Include one mixed set: a logic or algorithm problem, a few OOP multiple-choice items and one SQL query, all under a clock.
- Review every miss: write the cause (misread constraint, edge case, syntax, SQL logic) and the fix.
Deliverable: A scored timed session log with a cause and fix written for each miss, and a list of the three weakest topics to revisit.
Day 5 — Architecture, REST and microservices
- Write one example each for Singleton, Factory, Dependency Injection and Observer in your language, and note where each helps and where it causes problems.
- Design a small REST API for one resource: URIs, methods, status codes, how state is kept out of the server, and how clients retry safely.
- Write a monolith versus microservices comparison for modernising a legacy application, covering service boundaries, an API gateway, shared configuration and messaging.
- Describe how you handle logging, authentication and error handling across services, and how you keep data consistent between services with a message broker.
Deliverable: Four pattern examples, a one-resource REST API spec, a monolith-to-microservices trade-off page and a note on cross-cutting concerns and consistency.
Day 6 — Project stories for the technical validation interview
- Prepare a diagram of your most complex project and a narrative covering your role, the stack, the data model and two architectural decisions with the alternatives you rejected.
- Write the production bug or performance bottleneck story with the diagnostic steps in order: symptom, hypothesis, measurement, fix, prevention.
- Write a short answer on how you choose libraries, frameworks and tools for a new feature, and a story about quickly learning an unfamiliar technology.
- Write your position on balancing refactoring against a delivery deadline, with a real example, then answer the debugging and outage practice questions aloud.
Deliverable: A project diagram with narrative, a production incident write-up, a tool-selection answer, a learning-fast story and a refactoring-versus-deadline answer, plus spoken attempts at the two practice questions.
Day 7 — Client stage and full rehearsal
- Write your answer to communicating a technical trade-off to a non-technical manager, in English and Spanish.
- Write your changing-scope story using this order: restate, size, offer options, confirm in writing, outcome.
- Prepare questions for the client about project setup, team structure, domain and hybrid or remote work.
- Do a full spoken rehearsal in sequence, from the English introduction through the OOP and SQL answers to the project walkthrough, and log what fails.
Deliverable: A bilingual trade-off explanation, a written scope-change story, a list of client questions and a rehearsal log with the weakest answers marked for a final pass.
Project, client and communication stories
Candidates report that behavioural and background questions cover project history, a production bug, learning an unfamiliar technology quickly, balancing quality against deadlines, explaining technical trade-offs to non-technical people, handling changing client requirements and career goals, with an English introduction at the recruiter stage. Prepare four or five stories that you can reuse across these prompts, each with your own decision, what you measured and the result, and practise telling them in English as well as Spanish.
- How do you balance code quality and refactoring against tight delivery deadlines?
- How do you communicate complex technical decisions or trade-offs to non-technical business stakeholders?
- Describe a challenging bug or performance bottleneck you encountered in production and detail the exact steps you took to diagnose and resolve it.
- Tell me about an academic or professional project in which you had to master an unfamiliar technology or framework quickly.
- What are your career development goals for the next two to three years, and what technical domains do you want to master?
How do you handle changing scope or ambiguous project requirements requested directly by client management?
Medium · Communication & Multilingual Competency
Approach
- Choose a story from real client or stakeholder work where the requirement was vague or changed after you had started, and where you personally decided how to respond. A story where you simply carried out the change shows nothing.
- Show the sequence. First I restate the requirement in writing and list what is unclear; I turn each vague phrase into something testable, such as a number, an example input or an acceptance criterion; I confirm those with the person who owns the decision before I build further.
- For a change of scope, size it before you answer: what it costs, which delivered work it touches, and what would move. Then offer options (add it and move the date, swap it for something already planned, or defer it) instead of a flat yes or no, and record the agreement through the project's change process.
- Say how you protected the work already done, for example small increments, tests around the code the change touches, and a short demo so the client sees the effect early. Close with the outcome and one thing you would do differently.
- Avoid two mistakes: silently absorbing the change until the deadline slipped, and blaming the client. Example phrasing in your own voice: "I wrote back the three options with the effort for each, and the client chose the second."
Follow-up
- What did you do when the client changed their mind again after you had built the first version?
- How did you decide which requests to push back on and which to accept?
- What would you do if the client contact and your own tech lead gave you conflicting direction?
Narrate an outage you owned from page to postmortem
Hard · incident response · blast radius · postmortems
Pick an incident you personally drove, ideally one where writes were affected rather than reads. In six to eight minutes: state the symptom as it first appeared on a dashboard, the blast radius you established before you knew the cause, the mitigation you applied and when, the mechanism you eventually proved, and the follow-up that would prevent a repeat. Bring numbers: error rate, tenants affected, minutes to mitigate, minutes to resolve. If you cannot name what you measured, choose a different incident.
Approach
- Open on the signal rather than the cause: which metric at which percentile moved, on which service, at what time, so the listener follows the same evidence you had rather than a conclusion you already reached.
- Separate mitigation from diagnosis out loud. State what you did to stop the bleeding (flag off, shed traffic, drain a lease, roll back a deploy) and say plainly that you did it before the mechanism was known, because those are two jobs with different deadlines.
- Establish blast radius in countable terms: how many tenants, how many writes, and crucially whether the effect was loss or only delay. An append-only revision table or a pending outbox row means the change survived and the projection was merely behind, which is a repair rather than a data-loss incident.
- Prove the mechanism instead of asserting it. Name the trace span that grew, the plan that flipped to a sequential scan, the lease that expired, plus one alternative you ruled out and the signal that stayed flat while you ruled it out.
Follow-up
- What would you do differently in the first five minutes, given the same dashboard and no more information?
- Which follow-up action did you deliberately not take, and why was dropping it the right call?
Reverse your own decision and price the reversal
Medium · reversibility · measurement · migrations
Describe a technical decision you made and later reversed. Pick one that cost something: a service you split and merged back, a cache you added and removed, an index you created that pushed the planner onto a worse plan, a projection you rebuilt from scratch. State what you believed when you decided, the measurement that changed your mind, how long the wrong version ran in production, and what the reversal cost in migrations, dual writes, and a deprecation window for callers you did not own.
Approach
- State the original rationale without irony, in the version you would still defend given what was known then. If it is not defensible, the story is about carelessness rather than judgement, and a different example serves you better.
- Give the measurement that moved with a before and after: the p99 that did not improve, the cache hit rate that sat at 40%, the plan that flipped to a sequential scan once the table passed a size you can name.
- Cost the reversal in steps, not adjectives: expand-and-contract deploys, the dual-write window, the callers who had to be notified, the rows already written in the wrong shape that had to be backfilled or abandoned.
- Distinguish reversal from rewrite by naming what you kept. Most good reversals preserve the schema or the interface and undo one decision inside it, which is also why they were affordable.
Follow-up
- What in that decision was irreversible, and did you know it was irreversible when you made it?
- How did you tell the people who had already built on top of the original decision?