Interview guides · Amity University
Amity University Software Engineer Interview Guide
Amity University Software Engineer interview guide: 5 reported rounds, Java, OOP, DBMS, OS and Ansible questions, and a 7-day prep plan.
The 60-second brief
Amity University is an educational institution. Candidates describe the Software Engineer work as a mix of database, backend and deployment-automation tasks, mostly in Java, carried out alongside other university departments as well as other engineers.
This guide is for candidates applying as a Software Engineer at Amity University. It covers the five reported rounds, the reported fundamentals questions (Java, OOP, operating systems, DBMS, exceptions), the string-extraction and Ansible scenario questions, the behavioral and project questions, and a seven-day plan. It describes what candidates report, not a process the university has published.
Candidates report five rounds over roughly 4-6 weeks: Foundational Screening, Technical Assessments, Interpersonal Evaluations, Project Discussion and a Final HR Round. Other reports describe a shorter mix of aptitude, technical and HR stages, so confirm your own schedule with the recruiter.
Focus areas
- Object-Oriented Programming (OOP) concepts
- Ansible (automation & configuration management)
- Data Structures (DSA)
Overview
The reported question set falls into three clusters. The first is computer-science fundamentals: what the JDK is, the core ideas of object-oriented programming, what an operating system is and which types exist, the basics of a DBMS, and how Java handles exceptions. The second is practical problem solving: extracting data from a string, plus four Ansible scenarios (a playbook that fails on only some hosts, a slow playbook, a multi-region architecture, and a security patch across more than 1,000 servers with zero downtime). The third is behavioral: an introduction, what you expect from the role, and a walk-through of a past project.
The role description candidates give lists Java or C++, OOP, DBMS and operating systems as must-haves, with Ansible, the Spring framework and cloud deployment as nice-to-haves. Candidates also report topics such as memory management, concurrency in Java and choosing the right collection. That means fundamentals have to be answerable from first principles, not just recited: be ready to say what the JVM does with your code, why you would pick a HashMap over a TreeMap, how two threads can corrupt a shared counter, or what happens to a transaction when the server crashes.
The Ansible questions are scenario-based rather than definitions, and each has a repeatable shape: separate unreachable hosts from failed tasks, measure before tuning, shard by region, drain and verify before patching. Practise saying that sequence aloud with real module and setting names, and set it in a concrete university-style example of your own choosing: inventory groups split by campus, or a rolling patch of servers behind a system used by students and staff, scheduled away from exam or registration periods.
Finally, a full round is reported for discussing past projects. Choose two projects you built or changed yourself, and be able to describe the architecture, one bug or bottleneck you solved, how you worked with teammates and which tools (Git, Ansible or others) you used. The seven-day plan allocates a full day to this and to the introduction and expectations questions.
The Amity University interview process
Candidates describe five stages, listed below in the order they report them. Some reports also mention a group discussion, aptitude tests and a shorter total round count, so treat the order and count as typical rather than fixed. Because aptitude tests are mentioned, the plan includes a timed aptitude-style set.
Foundational Screening
Candidates describe this first stage as an initial check of basic technical skills and problem solving. The reported fundamentals questions are the natural material for a stage like this: the JDK, OOP, operating systems, DBMS and exception handling. Approach it by giving each topic a short definition, one contrast and one concrete example, rather than a long lecture. Since some reports mention aptitude tests, be ready for a written or multiple-choice format as well as spoken answers.
What to demonstrate
- Basic technical skills and problem-solving ability, as the stage is described
- Command of the fundamentals candidates report: Java, OOP, operating systems, DBMS
- Clear spoken explanation of a thought process
How to prepare
- Do a timed aptitude-style set: quantitative, logical and verbal questions, plus Java/C++ output-prediction and OS/DBMS multiple-choice questions
- Answer the JDK question by separating JVM, JRE and JDK and walking through javac then java on one small class
- Give a one-sentence definition and one example for each OOP pillar using a single Shape/Rectangle/Triangle example
- Rehearse the DBMS basics: keys, normalization to 3NF, ACID and what an index costs on writes
Technical Assessments
Reported as the stage where technical depth is checked across several assessments. Candidates report Java, C++, data structures, operating systems and Ansible scenarios as the technical territory, and string and data-structure questions are among the reported technical topics. Plan for follow-ups that move from a definition into how the feature behaves in a real system.
What to demonstrate
- Depth of knowledge in the technical areas reported for the role
- Correct reasoning on data structures, string handling and Java concurrency and memory
- Structured debugging and design reasoning for automation scenarios
How to prepare
- Write a signed-integer extractor in Java two ways (a Character.isDigit scanner and Pattern/Matcher with find()) and list the edge cases, including overflow on Long.parseLong
- Explain a count++ race and fix it with synchronized or AtomicInteger; contrast volatile (visibility) with synchronized (atomicity)
- Rehearse Java collections trade-offs: ArrayList versus LinkedList, HashMap versus TreeMap, ConcurrentHashMap versus Collections.synchronizedMap
- Walk through the four Ansible scenarios once each, naming real settings such as forks, serial, pipelining and max_fail_percentage
Interpersonal Evaluations
Reported as the conversational stage focused on communication and working style. Reports mention that some processes include a group discussion, so prepare for conversation as well as one-to-one answers. The reported behavioral questions (an introduction and what you expect from the role) are the material to rehearse.
What to demonstrate
- Communication and soft skills, the focus candidates report for this stage
- Explaining technical work to colleagues outside engineering, since the role is described as working with other departments
- A professional, respectful tone in discussion, including a group discussion where one is held
How to prepare
- Write a short introduction in present, past, future order with one measured technical achievement in the middle
- Prepare a story about explaining a technical problem, such as a failed deployment, to a non-technical colleague in plain terms
- Prepare one teamwork story that includes a real disagreement and what you conceded
- If a group discussion is possible, practise stating a point, linking to someone else's point, and summarizing
Project Discussion
This stage is reported as a discussion of your past projects. Reports say you should be able to walk through code or architecture, including technical hurdles, collaboration and tools such as Git or Ansible. Approach it as a guided tour of one project you can defend from the schema to the deployment.
What to demonstrate
- Ownership: what you personally designed, wrote or fixed
- Ability to explain architecture, challenges and outcomes
- Familiarity with the tools used, such as Git or automation tooling
How to prepare
- Pick two projects and write a one-page summary of each: problem, architecture, your role, one hard bug, one result you can measure
- Prepare to sketch the architecture and explain one decision and the alternative you rejected
- Rehearse the 'what would break at 100x load' follow-up, naming the first bottleneck and a fix
- If a teammate owned part of the project, be ready to say which part and what you learned from it
Final HR Round
The last stage is reported as a conversation with HR. Candidates report being asked to introduce themselves in almost every round, so rehearse that alongside the question on what you expect from the role. Candidates are also advised to show why they want to contribute to an educational institution, so prepare a short motivation answer. Keep answers consistent with what you said in earlier rounds.
What to demonstrate
- A professional, respectful and confident manner, which candidates report the university looks for
- Consistency between your earlier answers and your stated expectations
- A clear, specific reason for wanting to work in an educational institution
How to prepare
- Write a two-sentence answer to why this role and why an educational institution, grounded in the reported work (database, backend and deployment automation)
- Prepare a researched, flexible position on compensation in case it comes up
- Have three questions ready about the team and about what the first months of the role involve
- Re-read your project summaries so nothing contradicts what you said earlier
Where candidates lose points
Reciting a definition of the JDK, OOP or exceptions with no example or contrast
For each fundamentals question give a definition, one contrast and one concrete example. For the JDK, separate JVM, JRE and JDK; for exceptions, contrast checked and unchecked and show try-with-resources.
Answering the failing-on-some-hosts Ansible question with 'rerun it' or 'check the logs'
Open with the play recap, split unreachable hosts from failed tasks, rerun with a limit and verbose output, compare a good host with a bad one, then fix the playbook and confirm a clean second run.
Describing the 1,000-server patch as one run across every host
Describe a canary first, growing batches with serial, a failure threshold that halts the rollout, draining each host from its load balancer, a health check before it rejoins, and a rollback path.
A project walk-through that credits everything to the team and never separates your own work
Pick projects where you made the technical calls. State what you built, one decision with the alternative you rejected, the hardest bug and how you found it, and a measured result.
Skipping the basics because you know a framework such as Spring
Be ready to explain collections, memory management, concurrency and basic SQL from first principles, since fundamentals are listed among the reported topics.
Questions & practice
These questions test your ability to apply theoretical knowledge to real-world scenarios, particularly in auto
Medium · Practical Engineering & Problem Solving
These questions test your ability to apply theoretical knowledge to real-world scenarios, particularly in automation and coding.
Approach
- The questions below (string extraction, Ansible failures, speed, scale, and patching) all turn a concept into working automation. Practise the same shape on small tasks: parse a log, bulk-rename files, check disk usage across servers, or call an API and handle its errors.
- Build the script as parse, transform, output, each step testable on its own. Lean on the standard library (
pathlib,re,json,csv,subprocess,logging): it ships with Python, so the script runs on any host with Python and nothing to pip-install. - Make automation idempotent, so a second run changes nothing, e.g. check whether a line exists before appending. Pair it with atomic writes (temp file, then rename over the target) so a crash never leaves a half-written file; together they make reruns after a partial failure safe.
- Show the theory behind your choices: stream a multi-GB log line by line instead of calling
read()(constant memory), dedupe with aset(O(1) average membership) instead of scanning a list (O(n^2) overall), and count withcollections.Counter. - Handle failure like production code: non-zero exit codes on error, a timeout on every
subprocess.runand network call, a log of what changed, and a--dry-runflag that prints the actions without executing them. - Close with how you'd test it: a tiny fixture input, an assertion on the output, and a run against one host or directory before the whole fleet.
Follow-up
- How would you run it on a schedule and know it failed? Use cron or a systemd timer, log to a file or the journal, and alert on a non-zero exit instead of relying on someone noticing silence.
- How would you pass secrets such as API tokens to the script? Read them at runtime from environment variables or a secrets manager; never hard-code or commit them, or print them in logs or
--dry-runoutput. - How do you make a shell step safe to rerun? Guard it (
[ -f marker ] ||) or use idempotent commands (mkdir -p,ln -sfn), and addset -euo pipefailso a failure halts the script instead of running later steps on bad state.
How would you explain data extraction from a string?
Easy · Practical Engineering & Problem Solving
Approach
- Interpret it as pulling structured values (numbers, emails, dates,
key=valuefields) out of free text, and present three tools in increasing power: built-in string methods, regular expressions, and a real parser when the text follows a grammar. - Use
split,partition,find, and slicing when the format is fixed and delimiter-based, e.g.line.partition('=')forkey=value; they are fast, readable, and fail in obvious ways. - Reach for a regex when positions vary:
re.findall(r'-?[0-9]+', s)for signed integers, named groups for fields (adategroup matching[0-9]{4}-[0-9]{2}-[0-9]{2}), andre.compileonce when looping over many lines. - Don't regex-parse nested or quoted formats: use
json.loads, thecsvmodule (which handles quoted commas), or an HTML parser; a naivesplit(',')breaks on"Delhi, India". - Write a single-pass scanner: start a token at a digit (or a
-followed by a digit), extend while digits continue, then convert. The scan is O(n) time and O(k) extra space for k results, but eachint()is superlinear in its token's length on CPython, so huge digit runs dominate. - Test the edge cases: empty input, a lone
-,10-5(minus or negative?), leading zeros,'²'(isdigit()is true butint()raisesValueError), and runs over 4,300 digits, whichint()rejects since Python 3.11 (and 3.10.7, 3.9.14, 3.8.14, 3.7.14) unless you callsys.set_int_max_str_digits.
Worked solution (15 min)
- Agree on the contract first: return the integers in order of appearance, treat
-as a sign only when a digit follows, and accept ASCII digits only. - Scan with two indices:
ifinds where a token starts,jruns to the end of its digit run, thenint(s[i:j])is appended and scanning resumes atj, so each character is read once. - Write the one-line regex
-?[0-9]+alongside it and use it as an oracle: both functions must agree on every input you try, including random ones. - Justify
'0' <= c <= '9'overstr.isdigit(), which also accepts superscripts thatint()rejects, and over\d, which matches non-ASCII digits in Python.
import re
INT_PATTERN = re.compile(r"-?[0-9]+")
def is_ascii_digit(c: str) -> bool:
return "0" <= c <= "9"
def extract_ints(s: str) -> list[int]:
"""Return every integer in s, in order. A '-' is a sign only if a digit follows it."""
result = []
i, n = 0, len(s)
while i < n:
starts_number = is_ascii_digit(s[i]) or (
s[i] == "-" and i + 1 < n and is_ascii_digit(s[i + 1])
)
if not starts_number:
i += 1
continue
j = i + 1 # s[i] is a digit or the sign; extend over the digit run
while j < n and is_ascii_digit(s[j]):
j += 1
result.append(int(s[i:j]))
i = j # resume after the token, so each character is read once
return result
def extract_ints_regex(s: str) -> list[int]:
"""Same contract in one line; handy as an oracle when testing the scanner."""
return [int(tok) for tok in INT_PATTERN.findall(s)]
Expected result: extract_ints('order 42 shipped -7 days, id=007') returns [42, -7, 7]. Both versions scan in O(n) time with O(k) extra space for k numbers; each int() call is superlinear in its token's digit count on CPython, which the default 4,300-digit limit keeps bounded.
Verify it yourself
extract_ints('order 42 shipped -7 days, id=007')returns[42, -7, 7]extract_ints('')returns[]extract_ints('a - b --5')returns[-5]extract_ints('10-5')returns[10, -5]extract_ints('x²')returns[]
Follow-up
- How would you also extract decimals and scientific notation? Extend the pattern to
-?(?:[0-9]+[.]?[0-9]*|[.][0-9]+)(?:[eE][-+]?[0-9]+)?, convert withfloat, and test.5,5., and1e-3. - How would you pull
key=valuepairs from a log line? Use a regex with two groups, a word key and either a quoted string or a run of non-spaces, then strip the quotes somsg="disk full"stays one value. - How would you also return where each number appears? Use
INT_PATTERN.finditer(s)and collect(m.start(), int(m.group())), or recordiin the scanner before appending.
Your Ansible playbook is taking too long to execute. How would you optimize it for faster performance?
Medium · Practical Engineering & Problem Solving
Approach
- Measure before tuning: enable the
ansible.posix.profile_tasksandansible.posix.timercallbacks viacallbacks_enabledinansible.cfgto get per-task durations, then fix the few slowest tasks instead of changing settings blindly. - Raise parallelism: the default
forksis 5, so a 200-host run proceeds five hosts at a time; raising it to 50 or more (bounded by control-node CPU and memory) is often the biggest win. Check that no one setserial: 1orthrottlewithout need. - Cut SSH overhead: set
pipelining = True(sudoers must not requirerequiretty) so modules run without copying temp files, and keepControlPersistconnection reuse on so each task doesn't open a new SSH session. - Trim fact gathering:
gather_facts: falsefor plays that don't use facts,gather_subsetto collect only what's needed, and fact caching (gathering = smartwith ajsonfileorredisbackend) so repeat runs skip it. - Fix slow task patterns: pass a list to the
nameofpackage,apt, ordnfinstead of one task per package in a loop, setcache_valid_timeon apt cache updates, replace per-filecopyloops withsynchronizeorunarchive, and background long jobs withasync. - Consider
strategy: freeso fast hosts don't wait for the slowest at every task, then rerun the profile and compare total wall-clock time to confirm each change actually helped.
Follow-up
- Why doesn't
forks = 500inansible.cfg(or-f 500) make it 100x faster? The control node runs short of CPU and memory, and targets or shared services such as a package mirror start throttling; raise it in steps and measure. - When is
strategy: freeunsafe? When tasks depend on cross-host ordering, like migrating a database schema before app servers restart; the defaultlinearkeeps hosts in lockstep per task. - How does
asyncwithpoll: 0work? The task starts in the background on the target and returns a job ID; Ansible moves on, and you check completion later withasync_status.
Can you explain the fundamentals of DBMS?
Medium · Technical Fundamentals
Approach
- A DBMS is software that stores, retrieves, and manages data for many concurrent users while enforcing integrity, security, and crash recovery, all things flat files leave you to build yourself. A relational DBMS stores data in tables of rows and columns queried with SQL.
- Cover keys and constraints: a primary key uniquely identifies a row and can't be NULL; a foreign key references another table's key to enforce referential integrity; candidate keys are the minimal unique column sets;
UNIQUE,NOT NULL, andCHECKguard the rest. - Explain normalization as removing redundancy to prevent update anomalies: 1NF atomic values, 2NF no partial dependency on a composite key, 3NF no transitive dependency through non-key columns. E.g.
students,courses, and anenrollments(student_id, course_id)junction table. - Define transactions through ACID: atomicity (all or nothing), consistency (constraints hold before and after), isolation (concurrent transactions don't see each other's partial work, tuned by isolation level), and durability (committed data survives crashes, via write-ahead logging).
- Explain indexes: usually a B+ tree on one or more columns, turning a full scan into an O(log n) lookup and supporting range queries, at the cost of storage and slower writes. Indexing every column is a mistake, not a safety measure.
- Name the SQL sublanguages: DDL (
CREATE,ALTER,DROP), DML (SELECT,INSERT,UPDATE,DELETE), DCL (GRANT,REVOKE), and TCL (COMMIT,ROLLBACK).
Follow-up
- DELETE vs TRUNCATE vs DROP?
DELETElogs and removes matching rows, fires delete triggers, and can roll back;TRUNCATEis DDL that empties the table, skips delete triggers, and auto-commits in MySQL and Oracle;DROPremoves the table. - What are isolation levels? Read uncommitted, read committed, repeatable read, and serializable, each preventing more anomalies (dirty reads, non-repeatable reads, phantoms) at the cost of more locking or aborts.
- When would you denormalize? For read-heavy reporting where joins are the bottleneck, accepting duplicated data and the work of keeping the copies consistent.
Hold a per-tenant active cap against concurrent creates
Hard · write skew · isolation levels · constraints
A tenant on the standard plan may hold at most 50 resources with status='active'. The create handler runs SELECT count(*) FROM resource WHERE tenant_id = $1 AND status = 'active', compares to 50, then inserts. Two creates arrive 3 ms apart on different instances and the tenant lands at 51. Name the anomaly, say whether PostgreSQL 16 READ COMMITTED or REPEATABLE READ prevents it and why, then give an implementation that holds the cap at READ COMMITTED with the exact statements. Finally, say what changes when the cap is 'at most one running export per tenant' on job_run.
Approach
- Name it: write skew. The two transactions read an overlapping set and write disjoint rows, so there is no row-level conflict for the engine to detect and each commit is individually legal.
- Rule out the levels precisely. READ COMMITTED takes a fresh snapshot per statement and takes no lock on the counted rows, so both see 49. PostgreSQL's REPEATABLE READ is snapshot isolation: it removes non-repeatable reads and phantoms within the snapshot but still admits write skew, because the anomaly is not a re-read of a changed row, it is a read of a set that a concurrent transaction invalidates. Only SERIALIZABLE closes it, by tracking the read dependency and aborting one transaction with SQLSTATE 40001 — a guarantee that exists only if the application re-runs the whole transaction from the read.
- Convert the set predicate into a single-row conflict: keep tenant.active_resource_count and run UPDATE tenant SET active_resource_count = active_resource_count + 1 WHERE tenant_id = $1 AND active_resource_count < 50 in the same transaction as the INSERT. Zero affected rows is the cap, returned as 409. The row lock serialises the decision at any isolation level, and contention is bounded to one tenant's row — which is also the fair-scheduling unit, unlike a global counter that would convoy every tenant behind one row.
- State the cost you just took on: a counter is a second source of truth that can drift, so every path that changes status must adjust it inside the same transaction, and a periodic reconciliation has to exist, with resource_revision as the authority for what the count should have been.
Follow-up
- A resource moves from archived back to active. Which statements change, and what breaks if the counter update and the status change land in different transactions?
- The cap becomes plan-dependent and a plan can change mid-month. Where does the number 50 live, and who reads it?
Write the update path that detects a concurrent edit
Medium · optimistic concurrency · transactional outbox · audit history
resource carries version INT NOT NULL DEFAULT 1. resource_revision holds revision_id, resource_id, version, actor_user_id, change_kind, patch JSONB, request_id, created_at with UNIQUE (resource_id, version). outbox_event holds aggregate_type, aggregate_id, aggregate_version, event_type, payload, status. A PUT carries the version the client read. Write the exact statements for the single transaction that applies the edit, records the revision and enqueues 'resource.updated', and give the handler's branch on zero affected rows. Then say what PostgreSQL 16 does under READ COMMITTED when two of these updates hit one row at once.
Approach
- One transaction, three writes, no network call inside it: UPDATE resource SET title = $3, version = version + 1, updated_at = now() WHERE resource_id = $1 AND tenant_id = $4 AND version = $2; then INSERT the resource_revision row at version $2 + 1; then INSERT the outbox_event row at the same aggregate_version. The event goes to a table rather than a broker because no transaction spans both.
- Branch on the affected-row count before doing anything else. Zero has three causes — stale version, wrong tenant, row gone — so re-read once and map to 409 carrying the current version, or 404 for an id outside the caller's tenant, which also stops the endpoint confirming that another tenant's id exists.
- State the engine behaviour instead of assuming it. Under READ COMMITTED the second UPDATE blocks on the row lock, and when the first commits PostgreSQL re-evaluates the WHERE clause against the newly committed row, so the version predicate now fails and the statement reports zero rows. Under REPEATABLE READ the identical collision raises SQLSTATE 40001 instead, so the handler must fold both shapes into one conflict response.
- Keep UNIQUE (resource_id, version) even though the predicate already serialises writers. It is what makes a lost update unwritable if any other path ever reaches the revision table, and it converts a logic bug into 23505 rather than into a silently missing history row.
Follow-up
- A client sends the version it read ten minutes ago and the resource has moved three versions. What is in your 409 so it can resolve the conflict without a full re-fetch?
- Two editors, two disjoint fields, no overlap. Does your answer still refuse the second write, and should it?
These questions assess your grasp of foundational computer science principles, which are critical for the role
Easy · Technical Fundamentals
These questions assess your grasp of foundational computer science principles, which are critical for the role.
Approach
- This intro covers the concept questions below (Java, OOP, operating systems, DBMS, exceptions), so prepare those first, then the data-structure, complexity, memory, and networking basics they build on. Answer each with a one-line definition, one contrast, and one concrete example.
- Know the core costs cold: array index O(1), hash map lookup O(1) on average but O(n) in the worst case, balanced BST search O(log n), heap push/pop O(log n), and a lower bound of Ω(n log n) for comparison-based sorting.
- Explain stack vs heap memory: the stack holds call frames (locals, return addresses), is freed automatically when a function returns, and is small, so deep recursion overflows it; the heap holds dynamically allocated objects that live until freed or garbage-collected.
- Contrast TCP and UDP: TCP is connection-oriented with ordered, reliable delivery plus flow and congestion control (HTTP/1.1, SSH); UDP is connectionless and best-effort with less overhead (DNS lookups, voice calls, and QUIC under HTTP/3).
- Connect each structure to a use: a queue drives BFS, a hash set deduplicates n items in O(n) average time, a heap answers top-k in O(n log k), and a stack matches brackets.
- Derive complexity instead of reciting it: binary search halves the range each step, so O(log n); merge sort does O(n) merging on each of log n levels, so O(n log n); naive recursive Fibonacci is exponential until memoization makes it O(n).
Follow-up
- Why is hash map lookup O(n) in the worst case? Colliding keys share a bucket that lookup scans, though Java 8+
HashMaptreeifies a bucket past 8 entries (tables of 64+ slots) for O(log n) unless keys share a hash and aren'tComparable. - Array vs linked list? Arrays give O(1) indexing and cache-friendly scans but O(n) middle inserts; linked lists give O(1) insert or delete at a known node but O(n) access and poor locality.
- What happens when you type a URL into a browser? DNS resolution, a TCP (and TLS) handshake, the HTTP request and response, then parsing, fetching subresources, and rendering.
What is the JDK in Java?
Easy · Technical Fundamentals
Approach
- The JDK (Java Development Kit) is the toolkit for building Java programs: a Java runtime plus development tools such as
javac(compiler),java(launcher),jar,javadoc,jdb,jshell,jlink, andjcmd. - Separate the three layers: the JVM executes bytecode; the JRE is the JVM plus the standard class libraries needed to run programs; the JDK is the JRE plus the tools to compile, package, and debug.
- Walk the pipeline:
javac Main.javaproduces platform-neutral bytecode inMain.class;java Mainstarts the JVM, whose class loaders load it and whose bytecode verifier checks it during linking; then the interpreter runs it and the JIT compiler turns hot methods into native code. - Correct the classic misconception: the JVM is not platform-independent, since each OS and CPU needs its own JVM build. The bytecode is what's portable, which is where "write once, run anywhere" comes from.
- Mention versions and packaging: OpenJDK is the open-source reference implementation, several vendors ship builds of it, and production usually pins an LTS release (17, 21, 25). Since JDK 11 the reference builds ship no separate JRE (some distributions still do);
jlinkbuilds trimmed runtimes.
Follow-up
- What does the JIT compiler do? It profiles running bytecode and compiles hot methods to optimized native code (inlining, escape analysis), which is why Java programs speed up after warm-up.
- What is the classpath? The list of directories and JARs where class loaders look for classes, set with
-cporCLASSPATH; since Java 9 modular code uses the module path instead. - Can you run Java with only a runtime? Yes, running compiled
.classor.jarfiles needs just a JRE-style runtime; compiling needsjavac, which only the JDK has.
Explain the core concepts of OOPs (Object-Oriented Programming).
Easy · Technical Fundamentals
Approach
- Define OOP as modelling a program as objects that bundle state (fields) with behaviour (methods), created from classes. Then name the four pillars (encapsulation, abstraction, inheritance, polymorphism) and give each a one-line example.
- Encapsulation: keep fields
privateand expose only operations that preserve invariants, e.g.account.withdraw(amt)rejects overdrafts instead of letting callers setbalance. Generating a getter and setter for every field is not encapsulation. - Abstraction: expose what an object does and hide how, through interfaces and abstract classes, so callers use
Listwithout knowing it's anArrayList. Abstraction shapes the interface; encapsulation protects the implementation's data. - Inheritance: a subclass reuses and extends a parent (
class Car extends Vehicle) for a genuine is-a relationship, and must work anywhere the parent does (Liskov substitution). Prefer composition (has-a) when you only want to reuse code. - Polymorphism: one interface, many forms. Overloading (same name, different parameters) is resolved at compile time; overriding is runtime polymorphism, so
Shape s = new Triangle(); s.area()callsTriangle.area()through dynamic dispatch. - Tie all four to one example: an abstract
Shapewitharea(), private dimensions insideTriangleandRectangle, and a loop summing areas over aList<Shape>with noinstanceofchecks.
Follow-up
- Abstract class vs interface? An abstract class can hold state and constructors but a class extends only one; a class can implement many interfaces, which gained
defaultmethods in Java 8. - Why prefer composition over inheritance? Inheritance couples a subclass to the parent's internals (the fragile base class problem); composition lets you swap parts and keeps classes small.
- Can you override a static or private method? No: a subclass static method hides the parent's, so the call binds to the reference's declared type, and private methods aren't inherited, so a same-named subclass method is unrelated.
What is an operating system, and what are the various types of operating systems?
Easy · Technical Fundamentals
Approach
- An operating system is the software layer that manages hardware (CPU, memory, storage, devices) and gives programs safe abstractions over it: processes and threads, virtual memory, files, and I/O, all reached through system calls.
- Name its core jobs: CPU scheduling, memory management (paging, per-process virtual address spaces), file systems, device drivers, and protection. The kernel runs in privileged kernel mode, applications in user mode, crossing only via system calls, interrupts, or exceptions.
- List the types by how they run work: batch (queued jobs, no interaction), multiprogramming (several jobs in memory to keep the CPU busy), time-sharing or multitasking (fast switching gives each user an interactive share), and multiprocessing (several CPUs).
- Finish the list: distributed OSes (many machines presented as one system), network OSes (shared files and printers across a LAN), real-time OSes, and embedded and mobile OSes built for constrained or battery-powered devices.
- Define real-time precisely: it means predictable, bounded response times so tasks meet their deadlines, not raw speed. Hard real-time (airbag or pacemaker controllers) treats a missed deadline as failure; soft real-time (video playback) tolerates occasional misses with degraded quality.
- Add kernel architectures: monolithic (Linux, with loadable modules), microkernel (MINIX 3, seL4: user-space drivers, isolation at an IPC cost), and hybrid (Windows NT, macOS XNU). Shells and desktops run as user-space programs, though Windows keeps its win32k graphics subsystem in kernel mode.
Follow-up
- Process vs thread? A process has its own address space and resources; threads share their process's memory and open files but each has its own stack and registers, so switching is cheaper but needs synchronization.
- What is a context switch? The kernel saves one task's registers and state and restores another's; a process switch may also change page tables and flush TLB entries, so it costs more than a thread switch.
- What are the four conditions for deadlock? Mutual exclusion, hold and wait, no preemption, and circular wait; breaking any one, e.g. acquiring locks in a global order, prevents it.
How do you handle exception handling in Java?
Easy · Technical Fundamentals
Approach
- Start with the hierarchy: everything thrown extends
Throwable;Error(e.g.OutOfMemoryError) signals JVM-level problems you normally don't catch;Exceptioncovers recoverable conditions. Unchecked exceptions areRuntimeException,Error, and their subclasses; everything else is checked. - Contrast checked and unchecked: checked exceptions (
IOException,SQLException) must be caught or declared withthrows, enforced by the compiler; unchecked ones (NullPointerException,IllegalArgumentException) usually signal bugs and need no declaration. - Show the mechanics:
tryguards code;catchclauses are tried top to bottom and only the first match runs, so list subclasses first (a superclass first won't compile); multi-catchcatch (IOException | SQLException e)shares a handler;finallyruns whether or not anything was thrown. - Use try-with-resources for anything
AutoCloseable:try (var in = Files.newBufferedReader(p)) { ... }closes resources in reverse order even on failure, and an exception fromclose()is attached as suppressed instead of hiding the original. - State the practices: catch only what you can handle, never swallow with an empty
catch, wrap low-level exceptions with context while keeping the cause (throw new ConfigException("bad port", e)), log once at the boundary, and don't use exceptions for normal control flow. - Know the
finallytraps: it doesn't run if the JVM halts (System.exit, a crash), and areturninsidefinallyoverrides thetryblock's result and silently discards any exception in flight.
Follow-up
throwvsthrows?throwraises an exception object at a point in the code;throwsin a method signature declares the checked exceptions the method may pass to its callers.- Should a custom exception be checked or unchecked? Checked when callers can reasonably recover (retry, choose another file); unchecked for broken preconditions and bugs, which most modern APIs favour.
finalvsfinallyvsfinalize?finalblocks reassignment, overriding, or subclassing;finallyis the always-run block;finalize()was a GC hook, deprecated since Java 9 in favour ofCleanerand try-with-resources.
How would you design an Ansible architecture to scale across multiple regions with minimal overhead?
Hard · Practical Engineering & Problem Solving
Approach
- State requirements and assumptions: e.g. 3 regions with about 1,000 Linux hosts each and all changes through Git. Goals: low latency to hosts, a failing region never blocks the others, one source of truth, and no heavyweight agent on every host.
- Keep one Git repository of roles and collections with versions pinned in
requirements.yml, and packageansible-coreplus those collections into a container execution environment so every region runs identical code. - Generate inventory dynamically: a cloud inventory plugin (e.g.
aws_ec2) withkeyed_groupson region and role tags, plus layeredgroup_vars/all,group_vars/region_eu, and per-role vars, so adding a host needs no inventory edit. - Run execution close to the hosts: a lightweight runner (a control node or an AWX execution node) in each region, triggered centrally, so SSH never crosses regions. AWX's Receptor mesh supports this topology; a simpler version is CI jobs pinned to per-region runners.
- Decide push vs pull: regional push keeps ordering, central logs, and on-demand runs;
ansible-pullvia cron removes controller load but needsansible-core, Git, and repo credentials on every host, against the no-agent goal, and loses coordination. Push suits patching and ordered rollouts. - Plan for failure: deploy regions independently in a staged order (canary region first), keep every job idempotent so a failed region simply reruns, ship results to central logging through a callback plugin, and serve secrets from Ansible Vault or an external secret store.
Follow-up
- How do you stop a controller from becoming the bottleneck? Shard work by region and role, scale runners horizontally, and cache facts in Redis per region to cut per-run cost.
- How do you reach hosts in private subnets? Place the runner inside that network, or go through a bastion with SSH
ProxyJump, which adds latency and a single point of failure. - What happens when one region's runner is down? That region's jobs fail visibly while the others proceed; a standby runner in the same region, or a one-off run through a bastion, covers urgent changes until it's back.
You need to apply a security patch across 1,000+ servers using Ansible while ensuring zero downtime. What is y
Hard · Practical Engineering & Problem Solving
You need to apply a security patch across 1,000+ servers using Ansible while ensuring zero downtime. What is your approach?
Approach
- Zero downtime needs existing redundancy, so state the assumption: hosts sit behind load balancers or in clusters with spare capacity. Batch size is then capped by how many hosts each pool can lose at once without overloading the rest.
- Structure a rolling play:
serial: [1, "2%", "10%"]sends one canary first and grows the batches,max_fail_percentage(orany_errors_fatal: true) halts the rollout on a bad batch, and separate plays patch replicas before primaries. - Per batch,
pre_tasksdrain the host from the load balancer (adelegate_totask or an LB API call) and wait for connections to finish; then upgrade only the affected package:name: openssl,state: latest, andupdate_only: true(dnf) oronly_upgrade: true(apt). - Reboot or restart only when required: check
needs-restarting -ron RHEL-family hosts or/var/run/reboot-requiredon Debian/Ubuntu, use therebootmodule (it waits for the host to return), and otherwise restart just the services linked against the patched library. - Gate re-entry on health:
wait_forthe port and auricheck of the app's health endpoint, then re-enable the host in the load balancer inpost_tasks. A host that fails the check stays out of the pool and counts towardmax_fail_percentage. - Prepare and prove it: test the patch in staging, run
--check --diffagainst production, keep a rollback path (a pinned previous version or VM snapshot), and finish with a report of the installed version on every host to show full coverage.
Follow-up
- What if the canary fails its health check? The play stops on the failure threshold; leave that host drained, roll it back or rebuild it, and find the cause before resuming.
- Can you avoid kernel reboots entirely? Live patching (e.g. kpatch) applies some kernel fixes in memory, but you still schedule a reboot later to run the fully updated kernel.
- How long will 1,000 servers take? About the number of batches times (drain + patch + reboot + health check); with 10% batches after the canaries that's roughly a dozen waves, so batch size is the main lever.
You deployed an Ansible playbook, but it fails on some hosts while working on others. How would you debug and
Medium · Practical Engineering & Problem Solving
You deployed an Ansible playbook, but it fails on some hosts while working on others. How would you debug and resolve this?
Approach
- Read the
PLAY RECAPfirst and split the bad hosts into unreachable (Ansible never got a working connection) and failed (a task ran and errored). They have different causes, so debug them separately. - For unreachable hosts, test SSH alone with
ansible web01 -m raw -a uptime -vvv, then check the address and DNS, SSH user and keys,known_hosts, and bastion or firewall rules. A missing Python counts as failed, not unreachable: install it viarawor setansible_python_interpreter. - For failed tasks, rerun just those hosts with
--limit web01,web02 -vvvand read the module's real error. Diff a good host against a bad one:-m setupfor facts,ansible-inventory --host web01for inventory vars, and adebugtask for what that omits (role defaults, play and extra vars). - Rank the usual causes of host-to-host divergence: a different OS family or version (apt vs dnf, package names, paths),
group_vars/host_varsprecedence surprises,becomeor sudoers differences, a full disk, missing repo or proxy access, and drift from manual changes. - Fix the playbook rather than hand-patching hosts: branch on facts with
when: ansible_facts['os_family'] == 'Debian'or use the genericpackagemodule, add explicit preconditions withassertorstat, and preview with--check --diff. - Mitigate and verify: let healthy hosts finish, limit the blast radius next time with
serialandmax_fail_percentage, and rerun on the previously failing hosts twice; the second run should showchanged=0 failed=0, proving the fix is idempotent.
Follow-up
- The command works by hand but fails in Ansible. Why? Ansible runs non-interactively, without your login shell's
PATHand environment and possibly as another user viabecome; setenvironment:or use full paths. - How do other hosts keep going when one fails? By default a failed host is dropped from the rest of the play while the others continue;
block/rescueor a narrowignore_errorshandles known, benign failures. - How would you catch this before production? Test roles in CI against containers or VMs for every supported OS with Molecule, and run
ansible-linton each change.
Suggested practice checklist
Seven days built from the five reported rounds: an aptitude-style baseline, Java fundamentals with concurrency and memory, OS and DBMS, string handling in Java, the four Ansible scenarios with one idempotent automation script, and finally project and HR-style answers spoken aloud.
Day 1 — Map the loop and baseline your fundamentals
- Write the five reported rounds in order and next to each note what you would be asked to show: skills, depth, soft skills, projects, fit
- Do a timed aptitude-style set: quantitative, logical and verbal questions, plus Java/C++ output-prediction and OS/DBMS multiple-choice questions, and log every miss
- Time yourself answering each of the five fundamentals questions aloud and mark the two weakest
Deliverable: A one-page loop map, a scored aptitude set with misses explained, and a ranked list of your two weakest fundamentals topics.
Day 2 — Java core: JDK, exceptions and concurrency
- Explain JVM, JRE and JDK and trace javac then java for a small class
- Write a small program using try-with-resources, a custom checked exception that keeps its cause, and a finally trap you can explain
- Reproduce a count++ race with two threads, fix it once with synchronized and once with AtomicInteger, and explain volatile (visibility) versus synchronized (atomicity)
- Compare ExecutorService with raw Thread, and ConcurrentHashMap with Collections.synchronizedMap
Deliverable: A working Java file with exception handling, a race demo with both fixes, and a spoken two-minute answer on each of the JDK and exception questions.
Day 3 — OOP, memory and the fundamentals set
- Build one Shape example showing encapsulation, abstraction, inheritance and polymorphism without instanceof checks
- Answer abstract class versus interface and composition versus inheritance aloud
- Explain Java garbage collection as reachability from GC roots, write a leak through an ever-growing static collection, and contrast OutOfMemoryError with StackOverflowError
- Run through the general fundamentals checklist: complexities, stack versus heap, collections trade-offs, TCP versus UDP
Deliverable: A Shape example in Java or C++, a static-collection leak example, and a one-page complexity and memory cheat sheet written from memory.
Day 4 — Operating systems and DBMS
- Write out OS types with one example each, plus process versus thread, context switch and the deadlock conditions
- Design a three-table schema (students, courses, enrollments), normalize it to 3NF and write the join queries
- Explain ACID, isolation levels and what an index costs
Deliverable: A normalized schema with queries and a written one-paragraph answer on ACID and isolation levels.
Day 5 — String extraction in Java
- Implement signed-integer extraction in Java twice: a manual scanner using Character.isDigit, and a regex using Pattern and Matcher with find(); compare their complexity
- Write tests for empty input, a lone minus sign, 10-5, leading zeros and very long digit runs, where Integer.parseLong or Long.parseLong throws NumberFormatException on overflow; decide between rejecting the token and using BigInteger
- Note that Character.isDigit accepts non-ASCII digits, and decide whether your scanner should restrict itself to 0-9
- Extend the extractor to decimals and key=value pairs
Deliverable: Two working Java extractors with a test list covering every edge case above, including the overflow behaviour.
Day 6 — Ansible scenarios and idempotent automation
- Write the debugging sequence for the playbook that fails on some hosts: recap, unreachable versus failed, limit and verbose rerun, fact comparison
- List the settings that speed up a slow playbook (forks, pipelining, fact gathering, strategy) and the order you would measure and change them
- Sketch a multi-region architecture (shared roles, dynamic inventory, regional runners, staged rollout) and write a rolling patch play with serial, drain, health check and a failure threshold
- Write one idempotent automation script with a --dry-run flag, a timeout on every external call and non-zero exit codes on failure, then run it twice to show the second run changes nothing
Deliverable: A one-page runbook for each of the four Ansible scenarios, one rolling-patch playbook file, and one idempotent script with a dry-run mode.
Day 7 — Project, introduction and expectations
- Write and rehearse a short introduction in present, past, future order with one measured achievement
- Write a one-page summary for each of two projects, then talk through one aloud including the hardest bug and the trade-off you accepted
- Prepare answers to what you expect from the role, why an educational institution, and a teamwork story with a real disagreement
Deliverable: Two project summaries, a rehearsed introduction and written answers on role expectations and motivation.
Behavioural preparation
Candidates report an interpersonal stage, a project discussion and an HR round. The first three prompts below are the reported questions; the rest are practice prompts built around the reported work. Use the situation, task, action, result structure for scenario questions.
- Describe a time you debugged a failure that appeared in one environment but not another.
- Tell me about a time you explained a technical problem to someone outside engineering.
- Why do you want to work on technology in an educational institution?
These questions evaluate your communication, teamwork, and alignment with the professional culture at Amity Un
Easy · Behavioral & Situational
These questions evaluate your communication, teamwork, and alignment with the professional culture at Amity University.
Approach
- Show communication and teamwork through specific stories, not adjectives like "team player". Prepare four or five true, adaptable ones: a disagreement, a mistake or missed deadline, helping a teammate, explaining something technical, and taking ownership unasked.
- For communication, show you adapt to the listener, e.g. explaining a delay to a manager as impact and a new date rather than stack traces. Your delivery is evidence too, so keep each answer structured and under about two minutes.
- For teamwork, choose a story with friction rather than a smooth one: what you disagreed about, how you learned the other person's constraints, what you conceded, and the outcome. Stories where you were right and everyone else was wrong backfire.
- For professional culture, don't guess at values. Read the job description and the organization's own published material, then connect them honestly to how you already work, such as documentation habits, reliability, or keeping commitments.
- Include one story of working with non-engineers: how you turned a vague request into written, agreed requirements and kept them updated on progress. It covers communication and teamwork in a single answer, with your own actions told as "I", not "we".
Follow-up
- How do you check that your explanation actually landed? Ask the listener to restate the decision or next step, then send a short written summary of owners and dates after the conversation.
- How do you handle feedback you disagree with? Show that you ask for examples first, act on the valid part, and explain your view with evidence rather than defensiveness.
- Describe a time you missed a deadline. Own it, say when and how you raised the risk, what you cut or re-planned, and the habit you changed afterwards.
Can you tell us about yourself?
Easy · Behavioral & Situational
Approach
- This tests whether you can give a focused professional summary and steer the conversation toward your strengths; it isn't a request for your life story or a resume read-out. Aim for 60 to 90 seconds.
- Use present, past, future: what you do now (current role, or final-year studies and focus area), one or two past highlights that prove skill, and why this role is the logical next step.
- Make one highlight concrete, technical, and measured, e.g. "I built a Flask service that cut report generation from 20 minutes to 2". A specific achievement gives the interviewer something worth asking about.
- Choose highlights that match the responsibilities in the job description so the summary doubles as an argument for fit, and drop details like hometown or hobbies unless they show something relevant.
- End with a hook, such as the project you'd most like to discuss, which tends to pull the next question onto ground you've prepared. Rehearse aloud until it sounds natural rather than memorized.
Follow-up
- What are your strengths? Pick one or two that fit the role and back each with a short example instead of a list of adjectives.
- Why are you looking for a change? Stay forward-looking: what you want to grow into, never criticism of a current employer or team.
- Walk me through your resume. Go chronologically, spend the most time on the most relevant experience, and explain each transition in one sentence.
What do you expect from this role?
Easy · Behavioral & Situational
Approach
- This checks whether your expectations are realistic and match what the role offers, and whether you've read the job description. In an HR round it can mean salary, so ask one clarifying question if it's unclear.
- Name two or three concrete expectations tied to the described work: the problems you want to own, the technology you want to go deep in, and the feedback or mentorship you hope for. A bare "growth" says nothing.
- Pair each expectation with what you'll contribute, e.g. "I expect to own features end to end, and I'll bring my experience automating deployments"; expectations without contribution sound one-sided.
- Avoid answers centred on perks, titles, or moving to another team quickly, and keep expectations proportionate: expecting to lead a team within six months, with nothing in the role suggesting it, reads as a mismatch.
- If it means compensation, give a researched range based on market data for the role and location, say you're flexible on the overall package, and never name a number below what you'd accept.
- Turn it into a dialogue by asking what success looks like in the first six months; it shows you're calibrating your expectations against theirs.
Follow-up
- Where do you see yourself in five years? Describe a direction (deeper expertise, more ownership, mentoring others) the role plausibly supports, not a specific title.
- What if the role is more maintenance than new builds? Say where maintenance creates value: it's how you learn the system, and improving reliability or automating toil is real impact.
- How will you know after three months that the role meets your expectations? Name concrete signals such as shipping to production, owning a component, and regular feedback, and say you'd raise gaps early.
Explain a project you have worked on in the past.
Medium · Behavioral & Situational
Approach
- This tests depth and ownership: can you explain a real system clearly and defend its decisions under follow-up questions. Pick a project where you made the technical calls and know every part, not the biggest team project you touched.
- Open with a 30-second frame: the problem and who had it, the goal, your role, and the scale (users, data volume, team size). Then sketch the architecture in a sentence or two, e.g. "React front end, Flask API, PostgreSQL, deployed in containers".
- Spend most of the time on one or two key decisions: the options you considered, why you chose one, and the tradeoff you accepted, e.g. PostgreSQL over MongoDB because the data was highly relational, with many joins and foreign-key constraints a relational schema enforces for you.
- Include the hardest problem you hit (a bug, a performance issue, a design mistake): the symptom, how you narrowed down the cause, and the fix, e.g. a slow page traced with
EXPLAINto a missing index and resolved by adding one. - Finish with measurable results (latency, users, time saved, adoption) and one thing you'd do differently now, which shows reflection without undercutting the work.
- Prepare for the drill-down: your schema, one API endpoint in detail, how you tested, and how it was deployed. If a teammate owned a part, say so plainly rather than bluffing.
Follow-up
- How would it cope with 100x the users? Name the first bottleneck (often the database or a synchronous call), then the fix: indexes, caching, read replicas, or a queue for slow work.
- How did you test it? Cover unit tests for core logic, an integration test against a real database, and how you verified the deployment; admit gaps and what you'd add.
- What exactly was your contribution? List the components you designed or wrote and one decision you drove, keeping your work distinct from the team's.