cswork / libraryOpen practice workspace

Interview guides · American Technology Consulting

American Technology Consulting Software Engineer Interview Guide

American Technology Consulting Software Engineer interview guide: six reported rounds, Java, .NET, SQL and Flutter questions, answers and a 7-day plan.

The 60-second brief

Candidates describe the Software Engineer role at American Technology Consulting as building and maintaining applications for client businesses. The reported stack is broad: cross-platform mobile apps in Flutter, enterprise web applications in .NET and Java, and work against relational databases such as PostgreSQL, TeraData and SQL Server. Automation and identity management are named as areas the work touches, and the tasks candidates list include refactoring legacy code, integrating third-party APIs, writing automated tests and shipping through Git and Jenkins pipelines. That makes the role closer to a generalist application engineer than a specialist in one layer, so preparation should cover a language, a database and a delivery workflow rather than a single deep topic.

This guide is for candidates interviewing for the Software Engineer position at American Technology Consulting, from internship level upward. It covers the six reported rounds, the coding, database, framework and mobile questions candidates report, the behavioral questions that fit the managerial and leadership stages, and a seven-day plan. Reported requirements name at least one core language (C#, Java, JavaScript or Dart), data structures and algorithms, and working knowledge of a relational database.

Candidates report six rounds over roughly four to six weeks: Technical Screening, Coding Assessments, Technical Questioning, Live Coding Sessions, Managerial Interviews and Final Leadership Discussions. Round counts and formats are reported to vary by team, region and experience level.

Focus areas

  • DSA (Data Structures and Algorithms)
  • SQL
  • Flutter

Overview

The reported question set is a wide survey rather than a deep specialism. It spans Java and J2EE experience, differences between .NET framework versions, asynchronous programming and state management, SQL optimization, normalization and indexing, slow-query troubleshooting, Flutter and native mobile work, third-party API integration, Git and Jenkins, refactoring legacy code, and debugging a production issue. The practical consequence is that every technology on your resume is fair game, so build a short inventory of what you have used and be ready to go one level below the headline for each item.

Algorithm questions are reported as part of the loop too: the topic mix candidates describe lists data structures and algorithms, SQL, Flutter, programming fundamentals and algorithmic problem-solving. A function that finds the first non-repeating character in a string, how to work out the time complexity of a recursive algorithm, and how to debug a memory leak in a multi-threaded application are all reported examples. Prepare hash maps, strings, trees, sorting, searching and recursion, and practise narrating your reasoning while you write working code.

The back half of the loop shifts to people topics. Managerial Interviews are described as focused on collaboration and communication, and the final stage as conversations with leadership about cultural fit. The reported behavioral questions include working with a cross-functional team across time zones, prioritizing in an agile environment, handling code review feedback, and why you want this role. These deserve real stories with your own decisions in them, rehearsed as carefully as the coding rounds.

The American Technology Consulting interview process

Candidates describe six rounds that move from technical screening and coding tests to live coding, then managerial and leadership conversations. Exact formats are reported to differ by team and region.

Technical Screening

Candidates describe Technical Screening as the first assessment of technical skills and readiness, and some report that a loop can begin with just this one screen. The question types reported for the loop's early stages are language fundamentals, such as Java and algorithm concepts, and a summary of your J2EE experience. Approach it as a fast, accurate tour of the language you know best: short definitions, one concrete example from your own work for each, and a clear statement of where your experience ends.

What to demonstrate

  • Command of one core language such as C#, Java, JavaScript or Dart
  • Readiness to move on to the coding rounds
  • How precisely you describe technologies you list on your resume

How to prepare

  • Write a one-page inventory of the languages, frameworks and databases on your resume, with one project and one concrete problem for each
  • Answer the Java and algorithm concepts question and the J2EE experience question aloud, using one example from your own work per answer
  • Review object-oriented principles and the collections or standard-library structures of your main language

Coding Assessments

Coding Assessments are described as practical coding tests of problem-solving, and candidates note that written technical tests appear in some tracks. A test is where the algorithm questions are practised: strings, hash maps, sorting, searching and recursion. Approach it by writing a correct solution first, covering empty and degenerate inputs, and stating time and space complexity in a sentence at the end.

What to demonstrate

  • Working code on practical problems
  • Choice of data structure and awareness of complexity
  • Handling of edge cases

How to prepare

  • Implement the first non-repeating character function two ways, a counting hash map and a two-pass scan, and state the complexity of each
  • Practise explaining the time complexity of a recursive function using a recurrence, including a case with memoization
  • Work the data structure selection question: for each of array, hash map, tree and heap, write the access pattern it fits

Technical Questioning

Technical Questioning is described as direct questions about your resume plus deeper dives into coding and frameworks. This is where the framework and database questions are practised: lifecycle methods, asynchronous code and state management, .NET versions, SQL optimization, and normalization and indexing. Approach it by choosing, for each technology you list, one design decision you can defend and one thing that went wrong and how you fixed it.

What to demonstrate

  • Depth in the frameworks and tools listed on your resume
  • Ability to explain why you made a technical choice
  • Coding and framework understanding beyond definitions

How to prepare

  • For each framework on your resume, write down its component lifecycle, how it handles dependencies and how it manages state
  • Prepare a three-step explanation of tuning a slow SQL query: read the execution plan, check the index, rewrite the query
  • Build a short comparison of the .NET framework versions you have worked with, including what changed in tooling and runtime

Live Coding Sessions

Live Coding Sessions are described as interactive sessions in which you write code in real time. The skill being exercised is solving a problem aloud: restating it, naming an approach, writing it, then testing it against examples. Approach it by narrating the plan before typing, keeping functions small, and walking one example through your code before declaring it done.

What to demonstrate

  • Working code produced in real time
  • Clarity of reasoning while you code
  • Edge-case handling and debugging in an unfamiliar problem

How to prepare

  • Solve two problems a day in a plain editor while speaking continuously, then replay the recording and cut the silences
  • Practise debugging a short faulty function you did not write, isolating the failing input before changing anything
  • Write a SQL query against a sample table from scratch, then explain which index would serve it

Managerial Interviews

Managerial Interviews are described as focused on collaboration and communication within a team. The reported behavioral questions cover prioritizing tasks in an agile environment, working across time zones with a cross-functional team, and handling code review feedback. Approach it with stories where you can say what you decided, whom you informed, and what changed afterward.

What to demonstrate

  • Collaboration and communication within a team
  • Judgement about priorities and trade-offs in agile delivery
  • How you take and give feedback in code review

How to prepare

  • Write three STAR stories: a priority trade-off in a sprint, a cross-time-zone handoff, and a code review disagreement
  • Prepare how you explain a technical design choice to a non-engineer, using one real project
  • Review how you use Git branching, pull requests and Jenkins pipelines so you can describe your workflow concretely

Final Leadership Discussions

Final Leadership Discussions are described as conversations with leadership about cultural fit and final evaluations. The questions that fit this stage are your background and recent projects, and why you want to work as a Software Engineer here. Approach it with a coherent career narrative and a specific reason for choosing this role, drawn from its reported stack and client-facing work rather than from general praise.

What to demonstrate

  • Cultural fit as the round is described
  • Coherence of your background and motivation
  • Final overall evaluation of your candidacy

How to prepare

  • Write and rehearse a short background story that ends with the stack this role lists
  • Write your reasons for this role in three sentences, naming the web, mobile and database work you want to do
  • Prepare two questions about the team's projects and how engineers work with clients

Where candidates lose points

Coding in silence during the live coding session and presenting a finished function with no stated plan

Restate the problem, pick the data structure aloud, and walk a small example through the code at the end. For the first non-repeating character problem, say that a counting map plus a second pass is linear, then test an all-repeating string and an empty string.

Answering the slow-query question with "add an index" and nothing about how you found the problem

Describe the sequence: capture the slow statement, read the execution plan, check row estimates and scans, then choose between an index, a rewrite or a statistics refresh, and confirm the plan changed. Name the engine you have used for each step.

Telling every team story in the first person plural, so the managerial round cannot tell what you did

For each story, write one sentence that starts with "I decided" and says what the alternative was. Keep teammates' contributions in the story, but make your decision and its outcome explicit.

Listing technologies such as J2EE, TeraData or Flutter on your resume that you can only name, then getting stuck on a follow-up

Only keep technologies you can discuss one level deeper. For the rest, say "I have used X, not Y" and give the nearest equivalent you know, so a resume deep dive stays on ground you can defend.

Giving a generic answer to why you want this Software Engineer role at American Technology Consulting

Anchor the answer in the reported stack and tasks: web and mobile apps, enterprise databases, client work, legacy refactoring. Connect each to a project you have done and a specific thing you want to build.

Questions & practice

Can you explain basic Java questions and algorithm concepts?

Medium · Technical & Programming Fundamentals

Approach

  1. Open with the Java basics that keep coming up: == compares references and equals() compares values, String is immutable (literals are interned in the string pool), and any class that overrides equals() must also override hashCode() or HashMap and HashSet lookups break.
  2. Know collection costs. ArrayList gives O(1) index access and amortised O(1) append but O(n) insert in the middle. HashMap gets and puts are O(1) on average, and since Java 8 a heavily colliding bucket becomes a red-black tree. TreeMap is O(log n) and keeps keys ordered.
  3. Say which sort the JDK uses. Arrays.sort on primitives uses dual-pivot quicksort, which is not stable. Arrays.sort on objects and Collections.sort use TimSort, which is stable, O(n log n) in the worst case and close to O(n) on input that is already mostly sorted.
  4. Use one small problem to show the algorithm side, such as finding the first non-repeating character. Pass 1 counts characters in an int array or a LinkedHashMap, and pass 2 returns the first character with count 1. That is O(n) time and O(k) space for an alphabet of size k.
  5. Cover the rest of the fundamentals briefly. Checked exceptions must be declared or caught and unchecked ones need not be. Objects live on the heap and local primitives and references on the stack. Garbage collection reclaims objects that can no longer be reached.

Follow-up

  • What happens if you change a field used in hashCode() after the object is already a key in a HashMap?
  • When would you choose ConcurrentHashMap over Collections.synchronizedMap, and why?
  • How do you work out the time complexity of a recursive function such as naive Fibonacci?

How would you approach solving a complex algorithmic problem under a time constraint?

Medium · Problem-Solving & Data Structures

Approach

  1. Clarify the input size, value ranges, duplicates and expected output first, because the constraints set the target. Around n = 10^5 calls for O(n log n) or better, while n of about 20 allows O(2^n).
  2. Work a small example by hand and list edge cases before writing code: empty input, a single element, all elements equal, negative numbers, integer overflow.
  3. State a brute-force solution and its complexity out loud, then find the repeated work and pick the matching pattern: a hash map for lookups, sorting plus two pointers, a sliding window, prefix sums, BFS or DFS, a heap for top-k, or dynamic programming for overlapping subproblems.
  4. Write the code in small named helpers, explaining as you go. Trace your example and the edge cases through the finished code, then give the final time and space complexity.
  5. If time is running out, finish a correct brute force and explain the optimisation in words. A working O(n^2) solution is worth more than an unfinished O(n) one.

Follow-up

  • You have five minutes left and the optimal version still fails one case. What do you do?
  • Can you reduce the extra space your solution uses?
  • How does the solution change if the input arrives as a stream?

How do you determine the appropriate data structure for a given performance requirement?

Medium · Problem-Solving & Data Structures

Approach

  1. List the operations and how often each happens: lookup by key, insert, delete, ordered iteration, min or max, range query, FIFO or LIFO access. Then choose the structure whose costs fit that mix.
  2. Know the standard trade-offs. A hash map gives O(1) average lookup with no order. A balanced BST (TreeMap, SortedDictionary) gives O(log n) operations plus ordered, floor/ceiling and range queries. A heap gives O(1) peek and O(log n) push and pop for top-k or scheduling. A dynamic array gives O(1) index access but O(n) insert in the middle.
  3. Know the specialised structures: a deque for queues and sliding windows, a trie for prefix search, union-find for connectivity, and a hash map plus doubly linked list for an LRU cache with O(1) get and put.
  4. Look past Big-O to memory overhead, cache locality (arrays usually beat linked lists in practice), thread safety (ConcurrentHashMap) and worst cases versus averages, such as hash collisions.
  5. Check the choice against the stated requirement, for example 10k lookups per second over a million keys. If two structures each fit half the requirement, say which one you would compose or index on top.

Follow-up

  • You need the 10 most frequent items in a large stream. Which structures do you use, and at what cost?
  • What is a hash map's worst case, and what do real implementations do about it?
  • How would you support a query for all keys between two values?

What steps do you take to ensure your code is thoroughly tested and bug-free?

Medium · Problem-Solving & Data Structures

Approach

  1. Follow the test pyramid. Write many fast, isolated unit tests (JUnit, xUnit or NUnit, flutter_test), fewer integration tests against real dependencies such as a containerised database, and a small number of end-to-end tests (Selenium, Playwright or Flutter integration_test).
  2. Design cases from the inputs: equivalence classes and boundary values (0, 1, max, empty, null), invalid input and error paths. Use Arrange-Act-Assert so each test checks one behaviour.
  3. For every bug fixed, first write a test that reproduces it and fails, then fix the code. Mock only at system boundaries such as HTTP, the clock or the file system, because over-mocking ties tests to the implementation.
  4. Treat coverage as a signal, not a target. Branch coverage shows untested paths, but 100% coverage does not mean the code is correct. Run the suite in CI on every pull request, and quarantine and fix flaky tests rather than rerunning them until they pass.
  5. Be honest that "bug-free" is not achievable. Add code review, static analysis, and monitoring with alerts in production to catch what testing misses.

Follow-up

  • A test fails one run in twenty. How do you find the cause?
  • What would you test in a function that calls a third-party API?
  • Would you set a coverage target, and what number?

How do you write and optimize Structured Query Language queries for large datasets?

Medium · Database & Data Management

Approach

  1. Start from the grain of the result. Filter as early as possible with sargable predicates: write created_at >= '2026-01-01' AND created_at < '2027-01-01' rather than YEAR(created_at) = 2026, because wrapping the column in a function stops the planner from seeking on its index.
  2. Choose composite index order from the query: equality columns first, then the range column. Add INCLUDE columns (SQL Server, or PostgreSQL 11+) so the query is covered by the index alone. Select only the columns you need, never SELECT *.
  3. Read the actual plan: EXPLAIN (ANALYZE, BUFFERS) in PostgreSQL, the actual execution plan in SQL Server. If estimated and actual row counts are far apart, statistics are usually stale. Fix them with ANALYZE or UPDATE STATISTICS before rewriting anything.
  4. Avoid fan-out. Aggregate the many-side before joining it, and use EXISTS for semi-joins so rows do not multiply. Replace deep OFFSET pagination with keyset pagination (WHERE id > last_seen ORDER BY id LIMIT n), because OFFSET still reads and throws away every skipped row.
  5. For bulk writes on large tables, update or delete in batches by key range so locks, transaction-log growth and replication lag stay bounded. Mention date partitioning so queries skip partitions they do not need.

Follow-up

  • The plan shows a sequential scan even though an index exists. What are the possible reasons?
  • How would you delete 100 million old rows from a live table without blocking users?
  • Page 5,000 of a report has become very slow. What changes?

Can you explain the importance of database normalization and indexing?

Medium · Database & Data Management

Approach

  1. Define the normal forms precisely. 1NF means atomic values and no repeating groups. 2NF means no non-key column depends on only part of a composite key. 3NF means no non-key column depends on another non-key column. BCNF means every determinant is a candidate key.
  2. Explain why normalisation matters with an example. If an orders table repeats customer name and address, changing an address means editing many rows (update anomaly), and deleting the last order loses the customer (delete anomaly). Moving customers into their own table fixes both.
  3. Name when to denormalise: read-heavy reporting, or joins that are too expensive at scale. Name the cost too, which is keeping the copies consistent with triggers, materialised views or ETL.
  4. Explain indexing. A B-tree index turns a full scan into an O(log n) seek and supports range filters and ORDER BY. Every index adds write cost and storage, and an index on a low-selectivity column such as a boolean rarely helps.
  5. Mention two platform details. SQL Server allows one clustered index per table, whose leaf level is the table's rows. Neither PostgreSQL nor SQL Server indexes a foreign-key column automatically, so add those indexes yourself for joins and cascading deletes.

Follow-up

  • Does an index on (last_name, first_name) help a query that filters only on first_name?
  • Give a case where you denormalised on purpose. How did you keep the copies in sync?
  • Why might adding an index make a bulk insert job noticeably slower?

What are the key differences between various versions of.NET frameworks?

Medium · Technical & Programming Fundamentals

Approach

  1. Lay out the three lines. .NET Framework (1.0 to 4.8.1) runs only on Windows and now gets fixes but no new features. .NET Core (1.0 to 3.1) was a cross-platform, open-source rewrite. .NET 5 (2020) merged the two under one name and moved to yearly releases.
  2. Explain the support model. Even-numbered releases (.NET 6, 8, 10) are Long Term Support with three years of support. Odd-numbered releases are Standard Term Support with a shorter window. Client projects usually standardise on an LTS release.
  3. Name what did not carry over from the old Framework: ASP.NET Web Forms, server-side WCF (CoreWCF is a community port) and Windows Workflow Foundation. That list decides how hard a migration is.
  4. Contrast ASP.NET with ASP.NET Core. Core merged MVC and Web API, ships built-in dependency injection, replaces System.Web modules and handlers with a middleware pipeline, runs on Kestrel and reads appsettings.json instead of web.config.
  5. For a mixed estate, explain that a library targeting .NET Standard 2.0 can be shared by Framework 4.6.1+ and modern .NET. Mention the .NET Upgrade Assistant and a dependency inventory as the first steps of a migration.

Follow-up

  • How would you move an ASP.NET MVC app on .NET Framework 4.8 to .NET 8 without a big-bang rewrite?
  • Why do two different .NET versions sometimes behave differently with the same NuGet package, and how would you fix that?
  • What would you do with a WCF service that existing clients still depend on?

Can you explain how you would manage lifecycle methods in your preferred programming language?

Medium · Technical & Programming Fundamentals

Approach

  1. Pick one stack and go deep. In Flutter, a StatefulWidget runs createState, then initState (once), didChangeDependencies, build (many times), didUpdateWidget when the parent passes a new configuration, then deactivate and dispose.
  2. Say what belongs in each step. In initState, create controllers and subscriptions. Read InheritedWidgets such as Theme or Provider in didChangeDependencies, not initState. Keep build pure and cheap because it can run on every frame. In dispose, cancel StreamSubscriptions, timers and AnimationControllers.
  3. Cover the async trap. After an await, check mounted before calling setState, because the widget may already be disposed. Start fetches in initState, not build, or every rebuild sends a new network call.
  4. For app-level events, use WidgetsBindingObserver or AppLifecycleListener to react to resumed, inactive, paused and detached. Pause work and save state on paused.
  5. If your stack is Java or .NET, use the matching hooks: Spring's @PostConstruct and @PreDestroy, Android's onCreate through onDestroy, or .NET's IDisposable plus DI lifetimes (Singleton, Scoped, Transient). Avoid the captive-dependency bug where a singleton holds a scoped service.

Follow-up

  • What error do you get when setState runs after dispose, and how do you prevent it?
  • Where would you put a subscription that depends on a Provider value that can change?
  • What goes wrong when a singleton service takes a scoped DbContext in its constructor?

What database management system tools do you use for routine maintenance?

Medium · Database & Data Management

Approach

  1. PostgreSQL routine work: let autovacuum clear dead MVCC tuples and keep it tuned. Watch n_dead_tup and last_autovacuum in pg_stat_user_tables, because vacuum also prevents transaction-ID wraparound. Run ANALYZE so statistics stay current.
  2. For PostgreSQL bloat, use REINDEX CONCURRENTLY (PostgreSQL 12+) or pg_repack, which avoid the long exclusive lock that VACUUM FULL takes. Use pg_stat_statements and psql or pgAdmin for monitoring.
  3. SQL Server routine work: SQL Server Agent jobs or Ola Hallengren's maintenance scripts for index maintenance (reorganise light fragmentation, rebuild heavy fragmentation, as a rule of thumb), UPDATE STATISTICS, and DBCC CHECKDB for corruption checks.
  4. Backups: full, differential and log backups under the full recovery model in SQL Server, or pg_basebackup plus WAL archiving for point-in-time recovery in PostgreSQL. Tie the schedule to the RPO and RTO the application needs.
  5. Close with verification. A backup counts only once a test restore succeeds, so schedule restore drills and alert on failed or skipped maintenance jobs instead of assuming they ran.

Follow-up

  • How do you prove your backups can actually be restored?
  • A table has doubled in size on disk but not in row count. What happened, and how do you fix it without downtime?
  • Which maintenance tasks would you run only in a low-traffic window, and why?

How do you integrate third-party libraries and APIs into an existing application?

Medium · Web & Mobile Development

Approach

  1. Vet a library before adding it: its licence, recent maintenance, open security advisories, transitive dependencies and size. Pin the version with the lockfile (pubspec.lock, package-lock.json, Maven or NuGet) so every build resolves the same code.
  2. Wrap the dependency behind your own interface or adapter, and map the vendor's response objects to your own models at that boundary. The rest of the app then never imports the vendor directly, can be tested with fakes and can switch providers later.
  3. Make the API calls resilient. Set explicit timeouts. Retry with exponential backoff and jitter, but only for idempotent requests or requests carrying an idempotency key. Honour 429 responses and Retry-After. Use a circuit breaker so an outage at the provider does not hang your app.
  4. Keep secrets out of the client. A Flutter or web build can be decompiled, so route calls that need a secret through your own backend and keep keys in a secret store.
  5. Test against recorded or mocked HTTP responses, including errors and malformed payloads. In production, monitor the integration's latency and error rate separately from the rest of the app.

Follow-up

  • The vendor changes a response field without notice. How much of your code breaks, and how do you limit that?
  • A library you depend on has a published CVE and no patched release. What do you do?
  • How do you handle a request that timed out after the provider may already have processed it?

Can you explain basic HTML, CSS, and JavaScript concepts for web development?

Medium · Web & Mobile Development

Approach

  1. HTML: use semantic elements (header, nav, main, article, button rather than a clickable div), because they give keyboard and screen-reader support for free. Give images alt text and tie form controls to a label. Use ARIA only where no native element exists.
  2. CSS: explain the box model (content, padding, border, margin) and why box-sizing: border-box makes widths predictable. Explain specificity: inline styles beat IDs, IDs beat classes, attributes and pseudo-classes, and those beat element selectors. !important overrides all of them.
  3. Layout: flexbox for one-dimensional rows or columns, grid for two-dimensional layouts. Cover the position values (relative, absolute against the nearest positioned ancestor, fixed, sticky) and media queries for responsive design.
  4. JavaScript scoping: var is function-scoped and hoisted as undefined, while let and const are block-scoped and sit in the temporal dead zone until declared. A loop that uses var with setTimeout logs the final value every time, and let fixes it. Use === to avoid type coercion.
  5. JavaScript runtime: closures capture variables, not values. Arrow functions take this from the enclosing scope. The event loop runs all pending microtasks (promise callbacks) before the next macrotask (setTimeout). Event delegation attaches one listener to a parent and relies on bubbling.

Follow-up

  • In what order do console.log, setTimeout(fn, 0) and Promise.resolve().then(fn) print, and why?
  • What is the difference between event.preventDefault() and event.stopPropagation()?
  • How would you implement a debounce for a search input?

How do you manage version control and CI/CD pipelines using Git and Jenkins?

Medium · Web & Mobile Development

Approach

  1. Name a branching model and its trade-off: trunk-based development with short-lived feature branches (fewer painful merges, needs feature flags) or GitFlow with develop, release and hotfix branches (more ceremony, suits scheduled releases). Protect main with required reviews and passing status checks.
  2. Know the Git mechanics. Rebase private branches for clean history, but never rewrite a shared branch. To undo something already pushed, use git revert (a new commit) rather than reset. Resolve conflicts by understanding both changes, then rerun the tests. Tag releases.
  3. Keep the Jenkins pipeline as code: a declarative Jenkinsfile in the repo with stages for checkout, build, unit tests, static analysis, packaging, deploy to staging, integration tests, an input approval step and the production deploy.
  4. Use a multibranch pipeline triggered by repository webhooks so every pull request is built. Build the artifact once and promote that same artifact through environments instead of rebuilding it for each one.
  5. Keep secrets in the Jenkins Credentials store, injected with withCredentials, never in the Jenkinsfile. Publish test reports in a post { always { ... } } block, and have a tested rollback path such as redeploying the previous artifact.

Follow-up

  • A bad commit is on main and already deployed. What exactly do you do, step by step?
  • The pipeline has grown to 40 minutes. How would you speed it up? (Parallel stages, dependency caching, test splitting.)
  • How do you stop a credential from appearing in Jenkins console logs?

What is your approach to refactoring legacy code to improve readability and maintainability?

Medium · Web & Mobile Development

Approach

  1. Before touching anything, write characterisation tests that pin down what the code does today, odd behaviour included, so any later change in behaviour shows up as a test failure.
  2. Find seams for breaking dependencies: extract an interface, inject a dependency through the constructor, or wrap static and global calls. This lets you test the code without a database or network.
  3. Refactor in small steps that keep behaviour the same (extract method, rename, remove dead code, replace conditionals with polymorphism), and commit them separately from functional changes so each change can be reviewed and reverted on its own.
  4. Prioritise by hotspots: code that changes often and is also complex, taken from version-control history. Do not prioritise by how ugly the code looks. For larger replacements, use the strangler-fig pattern behind a feature flag rather than a big-bang rewrite.
  5. Show the result with something measurable: fewer bugs in the module, lower complexity, test coverage on the code you touched, or quicker changes afterwards. That is what justifies the time spent.

Follow-up

  • The code has no tests and the deadline is close. What is the minimum you do before changing it?
  • How would you persuade a lead to schedule refactoring time?
  • When is a full rewrite the right call instead of incremental refactoring?

Can you explain how you would design a simple proof of concept for an automation task?

Medium · Problem-Solving & Data Structures

Approach

  1. Pin down the manual process being replaced and the success measure (hours saved, fewer errors). Scope the proof of concept to one happy path that runs end to end on real sample data.
  2. Define the trigger (a cron schedule, a webhook or event, a file drop), the inputs and outputs, and where configuration lives. Keep it a small script or service rather than building a platform.
  3. Make it safe to rerun: record processed item IDs so a retry or duplicate trigger does not process anything twice. Add a dry-run mode that shows what would change without changing it.
  4. Handle failure explicitly. Retry transient errors, alert a person on hard failures, and never skip items silently. Log enough detail to audit each run.
  5. Run it under a least-privilege service account with secrets outside the code. List what the proof of concept leaves out (scale, UI, high availability), and show before-and-after numbers to decide whether to build the production version.

Follow-up

  • What changes when this proof of concept has to become a production system?
  • What happens if the job runs twice at the same time?
  • How do you decide whether a task is worth automating at all?

How do you troubleshoot a slow-running query or database bottleneck?

Medium · Database & Data Management

Approach

  1. Scope it first. Is it one query or the whole database? Since when? What changed: a deploy, data volume, a statistics refresh, a configuration change? A query that was fast last week and slow now often points to a plan change, not to the SQL text.
  2. Find the top offenders by total time: pg_stat_statements in PostgreSQL, Query Store or sys.dm_exec_query_stats in SQL Server. Then get the actual plan. EXPLAIN ANALYZE really runs the statement, so wrap any DML in a transaction and roll it back.
  3. Read the plan for the usual culprits: a full scan with a selective filter, estimated rows far from actual rows, a nested loop over a large outer input, a sort or hash that spills to disk, or an implicit type conversion that prevents an index seek.
  4. Separate slow from blocked. Check pg_stat_activity wait events and pg_blocking_pids() in PostgreSQL, or blocking_session_id in sys.dm_exec_requests in SQL Server. Also check CPU, I/O and connection-pool exhaustion before blaming the query.
  5. Change one thing at a time (an index, refreshed statistics, a rewrite) and measure again with the same parameters. Record the before and after plan and timing so the fix can be checked later.

Follow-up

  • A query is fast in SSMS but slow from the application. What could explain it? (Parameter sniffing, different SET options such as ARITHABORT.)
  • How would you tell lock contention apart from a bad execution plan?
  • What could you do immediately if you could not deploy a code change?

Can you walk through a time when you had to debug a difficult production issue?

Medium · Problem-Solving & Data Structures

Approach

  1. Choose an incident where you led the investigation. Open with the symptom in numbers (error rate, latency, how many users were affected) and who noticed it.
  2. Show that you mitigated before diagnosing: a rollback, a feature flag, a scale-up or a traffic shift to stop the damage, followed by the root-cause work.
  3. Walk through the evidence: logs, metrics and traces lined up against recent deploys, configuration changes or data changes. Then reproduce the problem in staging with production-like data, and narrow it down by bisection (git bisect or toggling components).
  4. Use the right tools for the problem. For a memory leak, compare heap dumps taken over time (jmap with Eclipse MAT for Java, dotnet-dump or dotnet-gcdump for .NET) and look for the objects whose count keeps growing. Separate the trigger from the underlying cause.
  5. Close with the permanent fix and prevention: a regression test, a new alert or dashboard, and a postmortem or runbook entry. A story that ends with "I restarted it and it went away" does not answer the question.

Follow-up

  • How did you confirm the fix worked and was not just a coincidence?
  • What monitoring would have caught this earlier?
  • What would you do differently if the same thing happened tomorrow?

Suggested practice checklist

The plan starts from a resume inventory, then covers the reported algorithm, database, framework, mobile and debugging topics, and ends with a full run of the managerial and leadership stories.

Day 1 — Resume inventory and experience stories

  • List every language, framework and database on your resume and mark each as deep, working or surface
  • Write a five-sentence answer for your J2EE experience, your PostgreSQL, TeraData or SQL Server experience, and your Flutter or native mobile experience
  • Write your background-and-recent-projects story in present, past, future order

Deliverable: A one-page inventory plus written answers for the J2EE, database, mobile and background questions.

Day 2 — Data structures and algorithm drills

  • Implement first non-repeating character in a string two ways and write the time and space complexity of each
  • Choose a data structure for three access patterns (lookup, ordered iteration, priority) and justify each in one sentence
  • Write recurrences for three recursive functions and solve their time complexity

Deliverable: Two working solutions with complexity notes, a data structure table, and three solved recurrences.

Day 3 — SQL optimization, normalization and indexing

  • Write a join with an aggregate on three sample tables, then read its execution plan and name the scan type used
  • Explain normalization through third normal form with one example table, and one case for denormalizing
  • Write your troubleshooting sequence for a slow query and the list of tools you use for routine database maintenance

Deliverable: A query with its annotated plan, a normalization example, and a step-by-step slow-query runbook.

Day 4 — Language fundamentals, .NET versions and async

  • Build a comparison of .NET Framework and modern .NET versions you have used, covering runtime, tooling and one breaking change
  • Write how component or object lifecycle methods work in your preferred language, with an example
  • Write an async example that handles cancellation and out-of-order responses, and describe where its state lives

Deliverable: A version comparison table, a lifecycle summary and a short async example with notes.

Day 5 — Web, mobile, integration and delivery

  • Write a three-paragraph summary of HTML, CSS and JavaScript fundamentals for a non-specialist
  • Outline how you integrate a third-party REST API into a mobile client, covering errors, retries and versioning
  • Describe your Git branching and Jenkins pipeline flow, then outline a refactoring plan for a legacy module

Deliverable: A web fundamentals summary, an API integration outline, a pipeline description and a refactoring plan.

Day 6 — Debugging, testing and proof of concept

  • Write your production debugging story using a timeline: symptom, hypotheses, evidence, fix and prevention
  • Outline a proof of concept for a small automation task, with scope, inputs, outputs and a test plan
  • Set a timer, solve one algorithm problem, and write what you did when you got stuck

Deliverable: A debugging story, a proof of concept outline and notes from one timed problem.

Day 7 — Managerial and leadership rehearsal

  • Rehearse stories on prioritizing in agile, time zones and code review feedback, each starting with what you decided
  • Write your answer to why you want this Software Engineer role, naming the stack and client work
  • Run a full mock of all six rounds in order, recording yourself, and list three fixes

Deliverable: Four rehearsed stories, a written role motivation answer and a fix list from the mock.

Stories for the managerial and leadership rounds

Candidates describe the Managerial Interviews as focused on collaboration and communication, and the final leadership conversations as covering cultural fit. For a Software Engineer role with cross-functional and client work, prepare stories that show your own decisions, how you communicated them, and what changed.

  1. Can you walk through a time when you had to debug a difficult production issue?

What is your experience with J2EE related technologies and frameworks?

Medium · Technical & Programming Fundamentals

Approach

  1. Describe one real J2EE project: what the application did, which container or server it ran on, and which parts you personally built. Name only the pieces you used, such as servlets, JSP, EJB, JPA, JMS or JNDI-configured data sources.
  2. Give a decision with trade-offs, for example where you placed transaction boundaries or whether business logic lived in session beans or plain classes, and what each choice cost.
  3. Include a concrete problem and its fix, such as lazy-loading N+1 queries or connection pool exhaustion, and say how you confirmed the fix, for instance by comparing query counts or pool metrics.
  4. If your experience is limited, say so, then map it to what you know. For example, explain how Spring or ASP.NET dependency injection and transaction handling compare with a Java EE container's.
  5. Finish with how you would approach a legacy J2EE codebase today: tests first, then incremental refactoring.

Follow-up

  • How does a servlet differ from an EJB, and when would you use neither?
  • How do container-managed transactions propagate between two components?
  • What changed when Java EE became Jakarta EE, and how would that affect migrating an old application?

How do you handle asynchronous programming or state management in your applications?

Medium · Technical & Programming Fundamentals

Approach

  1. Pick one real example and name the mechanism in your stack: Java's CompletableFuture or ExecutorService, C# async and await with Task, JavaScript promises, or Dart Futures and Streams.
  2. State the specific hazards you handled: out-of-order responses overwriting newer state, unhandled errors in background work, cancellation, and blocking a UI thread. In C#, mention not calling .Result or .Wait() on async code.
  3. Explain where state lives and why: one source of truth, immutable updates, and explicit loading, error and data states. If you used Flutter, name the approach you chose, such as setState, Provider or Bloc, and why it fit the screen's complexity.
  4. Give the outcome: a bug you removed or a screen that stopped flickering, and how you verified it with a test or a log.

Follow-up

  • How do you stop a slow earlier request from overwriting the result of a later one?
  • What happens to in-flight work when the user navigates away?
  • How would you test code that depends on timing?

What is your experience working with PostgreSQL, TeraData, or SQL Server?

Medium · Database & Data Management

Approach

  1. Be honest about scope: list which of PostgreSQL, TeraData and SQL Server you have used, in what role (developer or administrator), and against what data volume.
  2. For each engine give one concrete task. For PostgreSQL, reading EXPLAIN ANALYZE output or tuning an index. For SQL Server, reading an execution plan or choosing a clustered versus nonclustered index. For TeraData, choosing a primary index so rows distribute evenly, or collecting statistics.
  3. Show you know where the engines differ: PostgreSQL's multi-version concurrency and VACUUM, SQL Server's lock-based default isolation, and TeraData's parallel architecture where a skewed primary index causes a hot node.
  4. If you have not used one, say so directly and name the closest thing you have done, then explain how you would learn it, for example by reading the plan output of your first slow query.
  5. Close with a result: a query that went from slow to fast, with what you measured before and after.

Follow-up

  • How does MVCC in PostgreSQL differ from locking in SQL Server's default READ COMMITTED?
  • What makes a bad primary index choice in TeraData, and how would you spot it?
  • How would you migrate a table from one of these engines to another?

What is your experience building mobile applications using Flutter or native tools?

Medium · Web & Mobile Development

Approach

  1. Describe one shipped mobile app: platform targets, who used it, what you owned, and the key libraries. State whether you used Flutter, native Android or iOS tools, or both.
  2. Explain one design choice: for Flutter, how the widget tree is composed, StatelessWidget versus StatefulWidget, how you managed state and navigation; for native, how you structured screens and lifecycle handling.
  3. Compare the options honestly: Flutter gives a single Dart codebase for iOS and Android, while native gives direct access to platform APIs. Mention platform channels as the way to call native code from Flutter.
  4. Cover one real problem such as jank from unnecessary rebuilds, offline handling, or a third-party plugin that needed native work, and how you diagnosed it.
  5. If you have only built native or only Flutter, say that, then explain what you would expect to transfer.

Follow-up

  • How would you call a native-only API from a Flutter app?
  • How do you reduce unnecessary widget rebuilds?
  • How do you test a Flutter screen, and what separates widget tests from integration tests?

Can you tell me a little bit about your background and recent projects?

Medium · Behavioral & Cultural Fit

Approach

  1. Use a present, past, future order: what you do now, the two or three projects that got you here, then why this Software Engineer role is the next step.
  2. Choose one recent project and give its headline, your personal role, the stack, and one result you can quantify from your own work. Say "I" for what you did and name teammates for what they did.
  3. Pick technologies that overlap with the role's reported stack (Java, .NET, SQL, Flutter, Git and Jenkins) and be ready to discuss any item you mention one level deeper, since resume questions are reported.
  4. Avoid reading your resume aloud. End with one open thread, such as a technical decision you are proud of, that invites a follow-up.

Follow-up

  • Which technology in that project would you be comfortable going deep on, and why?
  • What would you change about that project if you rebuilt it?
  • What did you personally own versus the team?

How do you prioritize tasks when working in a fast-paced agile development environment?

Medium · Behavioral & Cultural Fit

Approach

  1. Name your decision rule and use it in the story: user or client impact, deadline, dependencies, and effort. Show you ranked by those, not by who asked loudest.
  2. Describe a concrete sprint where two items competed, what you chose to defer, and how you told the product owner or client the trade-off before it became a surprise.
  3. Cover interruptions: how you handled a production bug mid-sprint, and how you protected the sprint commitment or renegotiated it openly.
  4. State the result and one lesson, such as reserving capacity for support work or splitting a story so the valuable part shipped first.

Follow-up

  • Two stakeholders both say their task is urgent. What do you do?
  • How did you handle scope growth in the middle of a sprint?
  • When did you decide not to do something, and who did you tell?

Describe a time when you had to collaborate with a cross-functional team across different time zones.

Medium · Behavioral & Cultural Fit

Approach

  1. Pick a project with real separation: engineers, QA, product or client people in different time zones. Name the zones and what the overlap window allowed.
  2. Describe the working practices you set up: written handoff notes, pull request descriptions that stand alone, a decisions log, and a rule for what gets decided asynchronously versus on a call.
  3. Include one failure, such as a blocked day because a question sat unanswered overnight, and the specific change you made so it did not recur.
  4. Show you adapted your communication to the audience, with technical detail for engineers and impact and dates for clients and product owners.

Follow-up

  • How did you handle a decision that needed everyone but could not fit in the overlap window?
  • What did you do when a handoff was unclear?
  • How did you keep QA and development aligned on what was done?

How do you handle feedback during a code review?

Medium · Behavioral & Cultural Fit

Approach

  1. Show both sides: how you receive review and how you give it. Use one story where feedback changed your code, ideally one you first disagreed with.
  2. Describe your sequence: read it as being about the code, ask a clarifying question if the intent is unclear, check the claim with a test or a benchmark, then either change the code or explain your reasoning with evidence.
  3. Separate defects from preferences. Agree a team style guide or linter rule when it is only taste, and hold your ground with data when it is a real behavior or performance concern.
  4. Cover prevention: small pull requests, a self-review before requesting one, and a description saying what to look at. Avoid defensiveness and avoid agreeing to everything just to close the thread.

Follow-up

  • Tell me about feedback you disagreed with and what happened.
  • How do you give feedback on a teammate's pull request that has a serious flaw?
  • How do you keep reviews from blocking delivery?

Why do you want to work as a Software Engineer at American Technology Consulting?

Medium · Behavioral & Cultural Fit

Approach

  1. Build the answer from the role as candidates describe it: client-facing applications, a stack that spans Java, .NET, SQL databases and Flutter, work on legacy code and API integration, and a loop with live coding. Tie two or three of these to what you want to do and have done.
  2. Match your experience to the stack: name a project where you used a technology from the list and what it taught you.
  3. Say something you can only say about this role, such as wanting breadth across web, mobile and database work for clients, rather than praise any employer could receive.
  4. Do not claim facts about the culture or products you have not verified. If you researched the company, state exactly what you read and what you took from it.
  5. End with what you want to learn there and how your next year would use your background.

Follow-up

  • Why client-facing application work instead of a single product team?
  • Which part of the stack is newest for you, and how would you get up to speed?
  • What would make you decline an offer?