Skip to main content

Interview Questions

Every question has a short model answer and a link to the lesson example that shows it in code. Levels: F = Fresher (0-2 yrs), M = Mid (3-5 yrs), S = Senior (6-9 yrs), A = Architect / Lead (10+ yrs).

TopicFMSATotal
SQL Server89895927264
C#222214765
OOP272718981
Advanced C#272718981
Data Access242416872
Architecture141310441
Web API93946030277
Security151610647
System Design332311
Leadership12306

SQL Server

Tools

FWhat is the difference between SQL Server and SSMS?concept

SQL Server is the database server: a service that stores the data and runs queries. SSMS (SQL Server Management Studio) is a client tool that connects to SQL Server so you can write queries and manage objects. Uninstalling SSMS does not touch your data.

FWhat is LocalDB, and when would you use it instead of the Developer edition?concept

LocalDB is a lightweight version of SQL Server that starts on demand and needs no service setup; its server name is (localdb)\MSSQLLocalDB. It suits laptops with little memory and simple development. The Developer edition is a full server with every feature, such as SQL Server Agent, so it is better for realistic development and testing.

SWhich SQL Server edition would you use for development, testing, and the school's live server?design

Developer edition for development and testing: it has every feature and is free, but it is licensed only for non-production use. For the live server, Express is free but limited (for example, 10 GB per database). Most real schools need Standard edition, or a managed cloud database, depending on size, availability needs, and budget.

How to answer:

Separate the three environments and the licensing rule first. Size the SMS: one school's data fits Express for years, but 1,000 schools does not. Then weigh the trade-off: Express saves cost but has no SQL Server Agent for scheduled backups, so you would need another way to schedule them; Standard or a managed service costs more but handles backups and availability for you.

Scripts

MHow do you write a database script that can run more than once without errors?coding

Check before you create or change anything. Use IF DB_ID(N'SchoolDb') IS NULL before CREATE DATABASE, IF OBJECT_ID(N'dbo.Students') IS NULL before CREATE TABLE, and CREATE OR ALTER for views and procedures. Such scripts are called idempotent: running them twice leaves the same result as running them once.

MWhat does GO do in a SQL script?concept

GO is not a T-SQL command; SSMS and sqlcmd use it to split a script into batches and send each batch separately. Some statements, such as CREATE VIEW or CREATE PROCEDURE, must be the first statement in a batch. Variables declared before a GO do not exist after it.

RDBMS basics

FWhat is a relational database (RDBMS)?concept

A relational database stores data in tables made of rows and columns, and links tables to each other with keys. An RDBMS (Relational Database Management System), such as SQL Server, is the software that stores the data, runs queries, and enforces rules so many users can work safely at the same time.

FWhat are a table, a row, and a column?concept

A table stores one kind of thing, such as students. A row is one item of that thing, such as one student. A column is one detail that every row has, such as DateOfBirth.

FWhat is the difference between DDL and DML?concept

DDL (Data Definition Language) defines the structure: CREATE, ALTER, and DROP for tables and other objects. DML (Data Manipulation Language) changes the data inside them: INSERT, UPDATE, and DELETE. Creating the Students table is DDL; adding a student is DML.

MWhat are the system databases in SQL Server, and what does each one do?concept

master stores server-wide information such as databases and logins. model is the template copied for every new database. msdb stores SQL Server Agent jobs and backup history. tempdb holds temporary objects and work tables, and is recreated at every restart. Application tables never belong in any of them.

MWhat is the difference between SQL and T-SQL?concept

SQL is the standard language for relational databases. T-SQL (Transact-SQL) is Microsoft's extension of SQL for SQL Server. It adds variables, control flow such as IF and WHILE, and error handling with TRY...CATCH.

MWhat is a schema such as dbo, and why write dbo.Students instead of Students?concept

A schema is a named group of objects inside a database, used for organization and permissions; dbo is the default. Writing dbo.Students names the object exactly, so SQL Server does not have to resolve it per user. That is clearer, avoids picking the wrong object, and lets cached query plans be reused.

SA school keeps everything in spreadsheets and asks why it should move to a database. What do you tell them?scenario

A database lets many staff work at once without overwriting each other, enforces rules such as unique admission numbers and valid marks, and links data without copying it. It answers questions like "all of Kabir's absences this term" instantly, and adds security, backups, and an audit trail of who changed what.

How to answer:

Lead with the pain they already feel: lost changes, inconsistent copies, slow searches. Map each pain to a database feature with an SMS example. Be honest about the cost: setup, training, and someone to own backups, and propose moving one module first.

SWhat is tempdb used for, and why does it matter for performance?concept

tempdb holds temporary tables and table variables, and work areas for sorting, hashing, and row versioning. Every database on the server shares it. A busy or badly sized tempdb slows down every application on that server, so it is usually given several data files on fast storage.

How to answer:

Explain what goes into tempdb (explicit temp objects and internal work), then why sharing makes it a bottleneck. Give an SMS case: a large report that sorts 600,000 attendance rows spills to tempdb. Close with the trade-off: more files and fast disks help, but fixing the query so it sorts less helps more.

AWould you use a relational database or a NoSQL database for a School Management System? Why?design

A relational database. School data has a stable structure and strict rules: every mark belongs to a real enrollment, and fees must add up exactly across invoices and payments. Constraints and transactions enforce exactly that. NoSQL fits flexible documents or huge write-heavy workloads, which is not the core of a school system.

How to answer:

Start from the data's shape and rules, not from fashion. Name the relational strengths the SMS needs: constraints, joins, and transactions for fees. Then show balance: a NoSQL store could still fit a side feature, such as an activity feed or a search index, next to the relational core.

Data modeling

FWhat is an ER diagram, and what are entities and attributes?concept

An ER (Entity-Relationship) diagram is a picture of what a database stores and how the parts connect. An entity is a thing to remember, such as a student, and becomes a table. An attribute is a detail of an entity, such as a date of birth, and becomes a column.

FWhat are one-to-one, one-to-many, and many-to-many relationships?concept

One-to-one: one row on each side at most, such as a teacher and their login. One-to-many: one row links to many, such as a class and its sections. Many-to-many: many on both sides, such as students and guardians, which needs a junction table.

FGive an example of a one-to-many relationship and say where the foreign key goes.concept

A class has many sections, and each section belongs to one class. The foreign key always goes on the "many" side, so Sections has a ClassId column that points to Classes.

MHow do you implement a many-to-many relationship in tables?concept

Add a junction table with a foreign key to each side, and make the pair of keys its primary key. For students and guardians, StudentGuardians has StudentId and GuardianId; each row is one link.

MHow do you read crow's foot notation?concept

The symbols at each end of a line show how many rows can be on that side: || is exactly one, o| is zero or one, |{ is one or more, and o{ is zero or more. The three-pronged "crow's foot" means many. Classes ||--|{ Sections reads "one class has one or more sections".

MWhat is a junction table, and can it have columns of its own?concept

A junction table connects two tables in a many-to-many relationship. Yes, it can hold facts about the link itself. StudentGuardians stores Relationship (Father, Mother, Guardian) and IsPrimaryContact, because those describe the pair, not either side alone.

SWhy does the SMS have an Enrollments table instead of a SectionId column on Students?scenario

A student changes section every year. A SectionId on Students would overwrite last year's section and break the history of attendance, marks, and fees. Enrollments keeps one row per student per academic year, and everything year-specific links to it.

How to answer:

Explain that the section is a fact about a student in a given year, not about the student forever. Walk through Aarav in 9-A last year and 10-A this year. Mention the trade-off: queries need one more join, which is cheap compared to losing history.

SHow do you model a relationship that changes over time, such as which teacher teaches a subject?design

Make the relationship its own table and add the period it is valid for. In the SMS, SubjectAllocations links teacher, subject, section, and academic year, with a unique rule on (year, section, subject). Next year gets new rows, and old years stay correct for reports.

How to answer:

State the pattern (a time-scoped association table). Use the SMS allocation example and show how a past report card still shows the right teacher. Discuss the alternative of start and end dates, which handles mid-year changes but makes queries more complex.

AHow would you design attendance so it can later become per period without breaking existing data?design

Keep attendance in its own table linked to the enrollment, and plan an optional period column now. Daily records leave it empty; period records fill it, with a unique rule on enrollment, date, and period. Reports read both, so old data stays valid and new data adds detail.

How to answer:

Show that you design for likely change without building it all now. Describe the migration path (add a nullable column, add a new unique index, backfill nothing). Weigh it against a separate PeriodAttendance table, which is cleaner but means every report must read two tables.

Normalization

FWhat is normalization, and why do we do it?concept

Normalization is a set of rules for splitting tables so that every fact is stored once. It prevents update, insert, and delete anomalies, where copies of the same fact disagree or are lost. The usual target for business systems is third normal form.

FWhat is first normal form (1NF)?concept

A table is in 1NF when every cell holds a single value, there are no repeating columns such as Guardian1 and Guardian2, and every row can be identified by a key. A cell containing "Rajesh Sharma, Neha Sharma" breaks 1NF.

FWhat are update, insert, and delete anomalies?concept

An update anomaly: a fact stored twice is changed in one place only, so copies disagree. An insert anomaly: you cannot record one fact without another, such as a class teacher without a student. A delete anomaly: deleting one row removes an unrelated fact, such as a guardian's phone.

MExplain second normal form with an example.concept

A table is in 2NF when it is in 1NF and every non-key column depends on the whole key. In a table keyed by (AdmissionNumber, GuardianName), StudentName depends only on the admission number: a partial dependency. Moving student details to Students and guardian details to Guardians fixes it.

MExplain third normal form with an example.concept

A table is in 3NF when it is in 2NF and no non-key column depends on another non-key column. ClassTeacher on Students depends on the section, which depends on the student: a transitive dependency. Moving the class teacher to ClassTeachers (per section and year) fixes it.

MWhat is the difference between a partial dependency and a transitive dependency?concept

A partial dependency is a column that depends on only part of a composite key; 2NF removes it. A transitive dependency is a column that depends on the key only through another non-key column; 3NF removes it. Short test: a column must depend on "the key, the whole key, and nothing but the key".

SWhen would you denormalize, and how do you keep the copied data correct?concept

Denormalize when a measured performance or history need justifies a copy, such as an invoice total stored on FeeInvoices. Keep it correct with one owner: write it in the same transaction as the source rows, block other updates, or rebuild it on a schedule. Without an owner, copies drift.

How to answer:

Make clear denormalization is a deliberate trade-off, then give the SMS invoice total example with both reasons (speed, and a total that must not change after issue). Name the cost: more code paths to keep in sync, and the risk of drift if anyone forgets.

SThe fee report joins six tables and is slow. A developer wants to copy the student name onto FeePayments. What do you say?scenario

First measure: most slow joins are missing indexes or return too many rows, and copying the name fixes neither. If the report is still slow after indexing, consider a reporting view or summary table rebuilt on a schedule. Copying names onto payments creates a second place to update whenever a name is corrected.

How to answer:

Show you diagnose before redesigning: check the execution plan and indexes. Explain why this particular copy is risky (names get corrected and the copy goes stale). Offer the better options in order of cost: indexes, a narrower query, then a reporting table with a clear refresh owner.

Data types

FWhat is the difference between VARCHAR and NVARCHAR?concept

VARCHAR stores text in a limited code page, usually one byte per character, so letters outside it become ?. NVARCHAR stores Unicode, so any language works, at about two bytes per character. Use NVARCHAR for names, and write Unicode literals as N'...'.

FWhy should money use DECIMAL and not FLOAT?concept

FLOAT stores an approximation in binary, so values like 0.1 cannot be stored exactly and totals drift by tiny amounts. DECIMAL stores exact decimal digits. In SQL Server, 0.1 + 0.2 - 0.3 as FLOAT is about 5.55E-17, while as DECIMAL it is exactly 0.00.

FWhat is the difference between DATE and DATETIME2?concept

DATE stores only the day, which suits a date of birth or an attendance date. DATETIME2 stores the day and the time, with precision you choose; DATETIME2(0) keeps whole seconds. DATETIME2 replaces the older DATETIME, with a wider range and better precision.

MHow do you choose between TINYINT, SMALLINT, INT, and BIGINT?concept

Pick the smallest type that safely holds the largest value the column will ever need. TINYINT covers 0 to 255, SMALLINT about ±32,000, INT about ±2.1 billion, and BIGINT far more. For tables that grow with time, estimate rows per year times years of growth; attendance across many schools needs BIGINT.

MWhen would you use CHAR instead of VARCHAR?concept

Use CHAR(n) only when every value has the same short length, because it always uses n bytes and pads with spaces. Gender CHAR(1) is a good fit. For values of varying length, VARCHAR saves space; CHAR(50) stores a five-letter name in 50 bytes.

MWhat do precision and scale mean in DECIMAL(10, 2)?concept

Precision (10) is the total number of digits, and scale (2) is how many of them come after the decimal point. DECIMAL(10, 2) holds values up to 99,999,999.99, which is enough for any school fee.

SThe total of fees collected is off by 0.01 from the bank statement. How do you investigate?scenario

Check the data types first: a FLOAT or REAL amount column, or a FLOAT used in calculations, causes exactly this kind of drift. Then check rounding in code and reports, for example rounding each line versus rounding the total. Fix the type to DECIMAL and recalculate from the original payments.

How to answer:

Give a method: compare totals at each layer (database, API, report) to find where the difference appears. Explain the FLOAT cause with a concrete number. Close with the fix and its cost: changing a column type on a large table needs a migration, so it is cheaper to choose DECIMAL from the start.

SWhy store timestamps in UTC instead of local time?concept

UTC never changes with time zones or daylight saving, so every server, user, and report agrees on the same moment. Local times break when users or servers are in different zones, and some local times repeat or are skipped. Store UTC with SYSUTCDATETIME() and convert only for display.

How to answer:

Explain the problem with a concrete case: a payment at 11:30 PM local time lands on a different day in another time zone. Give the rule (store UTC, convert at the edges). Note the trade-off: every display needs a conversion, and dates without a time, like a date of birth, should stay plain DATE.

AWould you use INT IDENTITY or GUID (UNIQUEIDENTIFIER) primary keys?design

INT IDENTITY is 4 bytes and always increasing, so new rows go to the end of the index and joins stay fast. A GUID is 16 bytes and random, which fragments indexes, but it can be created anywhere without a central counter. Use INT or BIGINT for a single database, and GUIDs when many systems create rows independently.

How to answer:

Compare size, insert order, and index fragmentation, then the cases where GUIDs win: offline clients, merging databases, or not exposing a guessable Id in public URLs. Give the middle road: an INT key inside the database plus a GUID "public id" column for outside use.

Tables

FWhat does CREATE TABLE do, and what do you define for each column?concept

CREATE TABLE creates a new, empty table. For each column you define a name, a data type, and whether it allows NULL. You usually also define the primary key, and often other constraints, in the same statement.

FWhat is an IDENTITY column?concept

An IDENTITY(seed, increment) column is filled automatically by SQL Server. IDENTITY(1, 1) starts at 1 and adds 1 for each new row, so you never supply the value yourself. It is the usual way to create surrogate primary keys like Id.

FWhat is a primary key? Can it contain NULL or duplicate values?concept

A primary key is the column, or set of columns, that uniquely identifies each row. It can never contain NULL and never contain duplicates; SQL Server enforces both. A table has at most one primary key.

MWhy name constraints yourself instead of letting SQL Server name them?concept

SQL Server generates names like PK__Subjects__3214EC07A1B2C3D4, which differ on every server. Named constraints such as PK_Subjects appear clearly in error messages and can be referenced reliably in change scripts, for example to drop or alter them.

MDoes an IDENTITY column guarantee numbers without gaps?concept

No. A failed or rolled-back insert still uses up its number, and a server restart can skip a block of cached values. Gaps are normal: an identity value identifies a row, it does not count rows. If the business needs gapless numbers, such as invoice numbers, generate them separately inside a transaction.

MWhat is the difference between a master (lookup) table and a transaction table?concept

A master table holds lists that other data refers to and rarely changes, such as classes and subjects. A transaction table records events that happen all the time, such as attendance or payments. Transaction rows point to master rows, not the other way round.

SA deployment script fails in production with "There is already an object named 'Students'". How should deployment scripts be written?scenario

They should be idempotent: safe to run more than once. Each change checks first, for example IF OBJECT_ID(N'dbo.Students', N'U') IS NULL before CREATE TABLE, or COL_LENGTH before adding a column. Then a re-run after a partial failure, or a hotfix that already applied a change, does not break the release.

How to answer:

Name the principle (idempotent scripts), show the check pattern for tables, columns, and constraints, and explain the real cause: environments drift. Mention the trade-off: checks add lines to every script, while migration tools track applied scripts in a table instead.

SWhy does the SMS use an Id column as primary key instead of AdmissionNumber?design

Id is a surrogate key: small, never changes, and has no business meaning. AdmissionNumber is a natural key from the real world, and real-world values can change or be entered wrongly; changing a primary key means updating every foreign key that uses it. So the natural key is protected with a UNIQUE constraint instead.

How to answer:

Define surrogate and natural keys, then use the SMS case: a typo in an admission number must be fixable without touching attendance, marks, and fees. Note when natural keys are fine, such as small code tables that never change, and that you still enforce the natural key's uniqueness.

AHow do you manage database schema changes across development, test, and production over years?design

Every change is a versioned script stored in source control and reviewed like code. The same scripts run in the same order in every environment, usually through a migration tool that records which scripts were applied. Nobody changes production by hand.

How to answer:

Describe the pipeline: numbered, idempotent scripts, code review, automated deployment, and a record of applied changes. Compare approaches: migration tools that run scripts in order versus state-based tools that compare a model with the database. Mention the hard parts: data migrations on large tables, and rolling back.

Constraints

FWhat kinds of constraints does SQL Server support?concept

NOT NULL (a value is required), PRIMARY KEY (unique and not NULL), UNIQUE (no duplicates), CHECK (the value must pass a test), DEFAULT (a value when none is given), and FOREIGN KEY (the value must exist in another table). Together they keep data valid no matter which program writes it.

FWhat is the difference between a PRIMARY KEY and a UNIQUE constraint?concept

Both prevent duplicates. A table has only one primary key, and it never allows NULL. A table can have many unique constraints, and each allows one NULL. The primary key is the row's identity; unique constraints protect other business values such as a subject code.

FWhat does a foreign key do?concept

A foreign key makes a column's values refer to an existing primary key in another table. SQL Server then refuses a value that does not exist there, such as a section for class 99, and refuses to delete a row that is still referenced. This is called referential integrity.

MHow do you allow only one row to have IsCurrent = 1?coding

Use a filtered unique index: CREATE UNIQUE INDEX ... ON dbo.AcademicYears (IsCurrent) WHERE IsCurrent = 1. Uniqueness then applies only to rows that match the filter, so many past years can have 0 but only one year can have 1. A plain UNIQUE (IsCurrent) would wrongly allow only one past year.

MWhat happens if you delete a class that still has sections?concept

The delete fails with error 547: "The DELETE statement conflicted with the REFERENCE constraint FK_Sections_Classes". By default a foreign key blocks deleting a referenced row. You can choose ON DELETE CASCADE or SET NULL instead, but for school records blocking is safer.

MShould a rule like 'an academic year ends after it starts' be a CHECK constraint or application code?concept

Both, for different reasons. The application checks it to give the user a friendly message. The CHECK constraint guarantees it for every path into the database, including imports and manual fixes. A simple, permanent rule about one row belongs in a CHECK.

SYou need to add a foreign key to a table that already contains invalid rows. What do you do?scenario

First find and fix or archive the invalid rows, then add the constraint normally so SQL Server checks all existing data. WITH NOCHECK can add it without checking old rows, but the constraint is then marked untrusted, the optimizer cannot rely on it, and the bad data stays.

How to answer:

Show a safe process: measure the bad rows with a query, agree with the business how to fix each one, clean in a transaction, then add the constraint. Explain why WITH NOCHECK is only a temporary step, and that untrusted constraints lose query-plan benefits.

SA script that creates a filtered index works in SSMS but fails through sqlcmd. Why?scenario

Filtered indexes require QUOTED_IDENTIFIER ON. SSMS turns it on by default, but sqlcmd does not, so the CREATE INDEX fails with error 1934. Run sqlcmd with -I, or put SET QUOTED_IDENTIFIER ON in the script. Later inserts and updates on that table need the setting too.

How to answer:

Explain the session setting and why tools differ. Add the hidden danger: stored procedures and triggers remember the setting they were created with, so creating them through sqlcmd without -I breaks them later. Close with the fix: standardize the setting in every deployment tool.

AWhich business rules belong in database constraints, and which belong in application code?design

Rules that must always be true, whatever the context, belong in constraints: uniqueness, required values, valid ranges, and relationships. Rules that depend on who is acting, when, or on several steps belong in code: permissions, workflows, and time windows. Many important rules live in both places.

How to answer:

Give the test: "must this be true for every row, forever, from every source?" Use SMS examples on both sides (a mark belongs to an enrollment vs a teacher may edit marks only before results are published). Mention the cost of each: constraints are cheap and reliable but rigid; code is flexible but can be bypassed.

People tables

FWhy does the SMS store guardians in their own table instead of parent columns on Students?concept

A guardian is a person who can have several children in the school. With their own table, each guardian is stored once, with one phone number, and the StudentGuardians junction table links them to each child. Parent columns would repeat the same data for siblings.

FWhat is a composite primary key?concept

A composite primary key is made of two or more columns whose combination identifies the row. In StudentGuardians, (StudentId, GuardianId) is the key: one guardian can be linked to many students, but the same pair cannot appear twice.

FWhat is the difference between writing constraints inline and adding them with ALTER TABLE?concept

Inline constraints are written inside CREATE TABLE, either after a column or after all columns, so the whole definition is in one place. ALTER TABLE ... ADD CONSTRAINT adds a rule to a table that already exists. The result is the same; inline is simpler for new tables, ALTER for changes.

MWhy does Students.Status use a CHECK list instead of a separate lookup table?design

The list of statuses is short, fixed, and drives code behaviour, so a CHECK constraint is the simplest way to keep values valid. A lookup table is better when users must add or rename values without a code change, or when each value needs extra data such as a display name.

MHow would you guarantee that each student has at most one primary contact guardian?coding

Add a filtered unique index on StudentGuardians (StudentId) WHERE IsPrimaryContact = 1. Each student can then have any number of guardians, but only one row per student can be marked as the primary contact.

MWhy must tables be created in a particular order?concept

A foreign key can only reference a table that already exists. So tables that others point to, such as Students and Guardians, are created first, and tables that point to them, such as StudentGuardians, afterwards. Data must be inserted in the same order.

SA student leaves the school and rejoins two years later. How does this design handle it?scenario

The student keeps the same Students row and admission number; their status changes to Withdrawn when they leave and back to Active when they return. The gap years simply have no enrollment, and the return year gets a new Enrollments row. History before and after stays connected to one person.

How to answer:

Separate the person (permanent) from the yearly placement (enrollments). Walk through the rows that change. Mention the alternative some schools want, a new admission number on return, and why it splits one student's history in two.

SThe people tables hold personal data. What would you do to protect it?design

Collect only what the school needs, restrict who can read sensitive columns, and use made-up data in development and test. SQL Server features such as permissions on columns or Dynamic Data Masking can hide values from users who do not need them, and backups must be protected like the live database.

How to answer:

Cover the principles (minimize, restrict, protect copies) before the features. Use SMS examples: a teacher needs a guardian's phone, but not every guardian's occupation. Note the trade-off: tighter access adds work for support staff, so define roles carefully.

AWould you store teachers, students, and guardians in one People table or in separate tables?design

Separate tables, as in the SMS, are simpler: each has its own columns and rules, and queries stay clear. A single People table (a supertype) avoids repeating name and contact columns and suits people with several roles, such as a teacher who is also a parent, but it adds joins and nullable role-specific columns.

How to answer:

Present both designs fairly, then decide from the requirements: how often one person has several roles, and how different the roles' data is. Mention the middle path: separate tables now, plus a shared Users table for login, which is what the SMS does.

Enrollment

FWhat is a unique constraint on multiple columns?concept

It makes the combination of the columns unique, not each column on its own. UNIQUE (StudentId, AcademicYearId) lets a student appear once per year, so the same student can still have one row for every year.

FHow does the database stop two students getting the same roll number in a section?concept

With UNIQUE (SectionId, AcademicYearId, RollNumber) on Enrollments. Roll number 3 can exist in 10-A and 10-B, and in 10-A next year, but only once in 10-A in the same year.

FWhat does an enrollment represent in the SMS?concept

One student in one section for one academic year, with a roll number. Attendance, marks, and fee invoices all link to the enrollment, so every record knows which year and section it belongs to.

MWhy do the SMS unique rules on Enrollments include AcademicYearId?concept

Because the facts they protect are true per year. A student is in one section per year, and roll numbers repeat each year. Without the year, UNIQUE (StudentId) would allow a student to be enrolled only once in their life.

MWhy is the class teacher stored in a ClassTeachers table instead of a column on Sections?design

The class teacher changes every year, while a section such as 10-A exists every year. A column on Sections would be overwritten each year and lose history. ClassTeachers keeps one row per section per year, protected by UNIQUE (AcademicYearId, SectionId).

MWhat does SubjectAllocations store, and which rule protects it?concept

It stores which teacher teaches which subject to which section in each academic year, with four foreign keys. UNIQUE (AcademicYearId, SectionId, SubjectId) ensures one teacher per subject per section per year, while one teacher can still teach many sections.

SA student moves from 10-A to 10-B in the middle of the year. How do you handle it with this design?scenario

The simple design allows one enrollment per year, so you correct the section on the existing enrollment and record the change in the audit columns. If the school needs to know which section the student was in on each date, the design must change: add a "valid from" date and one row per move, and adjust the unique rules.

How to answer:

Show that you see the hidden requirement: does history per date matter? Compare the two designs and their costs (simple updates vs more complex queries). End with the process: agree the rule with the school before coding, because both are valid.

SHow would you stop a section from going over its capacity of 40 students?design

A constraint cannot count rows, so this needs logic: a stored procedure or the API checks the current count before enrolling, inside a transaction that locks the section, so two enrollments at the same moment cannot both pass. A trigger can act as a safety net.

How to answer:

Explain why CHECK and UNIQUE cannot do it, then show the race condition: two clerks enrolling the 40th student at once. Describe the fix with a transaction and lock, and mention the trade-off between enforcing in the database (safe) and in the API (easier to show friendly messages).

AHow would you design the year-end rollover that promotes 10,000 students to the next year?design

Create the new academic year, then insert next year's enrollments in one set-based statement from this year's enrollments, moving each student up a class. Run it in a transaction, make it safe to re-run, and produce a review report first so the school can correct exceptions such as students who repeat a year or leave.

How to answer:

Cover the steps (prepare, preview, execute, verify) and the guarantees (all or nothing, re-runnable, auditable). Discuss the exceptions that need human decisions, and the trade-off between a fully automatic job and a reviewed, two-step process.

Attendance and marks

FWhy is the key of AttendanceRecords a BIGINT?concept

Attendance grows by one row per student per school day. One school of 10,000 students adds about 2 million rows a year, and many schools together pass the 2.1 billion limit of INT. BIGINT costs four more bytes per row and removes that risk.

FHow does the database prevent marking a student's attendance twice on the same day?concept

With UNIQUE (EnrollmentId, AttendanceDate) on AttendanceRecords. A second record for the same enrollment and date is refused, so a double click or a network retry cannot create a duplicate.

FWhy store NULL marks for an absent student instead of 0?concept

Zero means "attended and scored nothing"; absent means "did not write the paper". Storing 0 would lower averages and show a misleading report card. MarksObtained is NULL and IsAbsent is 1, so reports can treat absence correctly.

MExplain the CHECK constraint that combines IsAbsent and MarksObtained.coding

CHECK ((IsAbsent = 1 AND MarksObtained IS NULL) OR (IsAbsent = 0 AND MarksObtained >= 0)) allows only two valid states: absent with no marks, or present with marks of zero or more. It refuses "absent with 45 marks" and "present with no marks". A CHECK can compare columns of the same row like this.

MWhy is there an ExamSubjects table between Exams and Marks?design

An exam such as "Unit Test 1" has many papers: one per class and subject, each with its own date, maximum marks, and pass marks. ExamSubjects stores those papers, and each mark belongs to one paper. Without it, every mark would have to repeat the paper's details.

MWhy can't a CHECK constraint enforce 'marks cannot exceed the paper's maximum'?concept

A CHECK constraint can only see the row being saved. The maximum lives in ExamSubjects, another table. Cross-table rules need a trigger, a stored procedure, or application code; the SMS adds a trigger in Lesson 23 and the same check in the API.

SEvery class teacher saves attendance between 8:45 and 9:00 AM. What design concerns does that create?scenario

Thousands of inserts arrive in a few minutes, so saves must be fast and safe to retry. Save a whole section in one set-based statement inside a transaction, rely on the unique constraint to stop duplicates, use an "insert or update" approach for corrections, and keep the table's indexes minimal so inserts stay cheap.

How to answer:

Describe the load pattern first (short, intense peak). Then cover correctness (unique rule, idempotent saves), efficiency (one statement per section, not one per student), and the trade-off between extra indexes for reports and insert speed at peak time.

SA mark must be corrected after report cards were printed. How should the system handle it?scenario

Allow the correction only for authorized roles, record who changed it and when in the audit columns, and keep the old value in an audit log or history table. Reprint the affected report card and keep the reason for the change. A silent overwrite would make the printed and stored marks disagree with no explanation.

How to answer:

Combine process and design: permissions, audit trail, and a reason field. Name the SQL Server options for keeping old values (an audit table written by a trigger, or a system-versioned temporal table) and the cost of each in storage and complexity.

AHow would you store ten years of attendance for 1,000 schools?design

That is billions of rows, so plan for size from the start: BIGINT keys, partitioning by date so old periods can be managed separately, archiving closed years to cheaper storage, and summary tables for reports that need totals rather than single days. Daily screens then only touch the current year's data.

How to answer:

Estimate the volume with numbers first. Then explain each technique and what it solves: partitioning (maintenance and fast removal of old data), archiving (cost), summaries (report speed). Close with the trade-off: more moving parts to operate, justified only at that scale.

Fees and audit

FWhat are audit columns?concept

Columns that record who created a row and when (CreatedAt, CreatedBy), and who last changed it and when (UpdatedAt, UpdatedBy). CreatedAt usually has a default of SYSUTCDATETIME(). They answer "who and when" for the latest change, not the full history.

FWhat is soft delete?concept

Instead of removing a row with DELETE, you mark it as deleted with IsDeleted = 1 and a DeletedAt time. Screens and reports leave those rows out, and the row can be restored by setting the flag back.

MWhat are the downsides of soft delete?concept

Every query must filter IsDeleted = 0, and forgetting it shows deleted rows in reports. Unique constraints still see deleted rows, so a deleted record's unique value stays taken. Tables never shrink. Use it only where restore or history is required, and hide the filter in views.

SWhen are audit columns enough, and when do you need a full audit history?design

Audit columns record only the latest change, which is enough for "who touched this last". When you must know every old value, such as for marks or payments, you need a history: an audit table filled by triggers, a system-versioned temporal table, or change data capture. Each keeps old versions at the cost of storage.

How to answer:

Start from the question the business needs answered, then match a tool: audit columns, temporal tables (automatic history per table), or an audit log (custom, can include the reason). Mention storage growth and how long history must be kept.

MHow do you add a NOT NULL column to a table that already has rows?coding

Add it with a default in the same statement, for example ALTER TABLE dbo.Students ADD IsDeleted BIT NOT NULL CONSTRAINT DF_Students_IsDeleted DEFAULT (0). Existing rows get the default value. Without a default, the statement fails because existing rows would have no value.

FWhy are invoices stored as a header table and a lines table?design

The header (FeeInvoices) holds facts about the whole bill: number, date, student, total, status. Each line (FeeInvoiceItems) holds one fee type and amount. One fact per row means any number of fee types per invoice, and reports can total tuition or exam fees across all invoices.

MHow does the SMS support part payments, and how do you calculate an invoice's balance?concept

An invoice can have many rows in FeePayments. The balance is the invoice total, minus its discount, minus the sum of its payments. The invoice status (Unpaid, PartiallyPaid, Paid) is updated in the same transaction that records a payment.

SA parent double-clicks 'Pay' and two identical payments are recorded. How do you prevent that?scenario

Make the payment request idempotent: the client sends a unique payment reference, and a unique constraint on it refuses the second insert. Record the payment and update the invoice status in one transaction, and have the screen disable the button after the first click. The database rule is what makes it reliable.

How to answer:

Explain the cause (retries and double clicks happen), then layer the defences: UI, API idempotency key, unique constraint, and a transaction. Name the trade-off: you need a reference that the client generates once per payment attempt.

Inserting data

FWhat is the syntax of INSERT, and why should you always list the columns?coding

INSERT INTO dbo.Table (Col1, Col2) VALUES (v1, v2), (v3, v4); adds one or more rows. Listing the columns keeps the insert working when columns are added later, and stops values going into the wrong columns if the column order changes.

FWhat happens to a column you leave out of an INSERT?concept

SQL Server uses the column's DEFAULT if it has one, the next value if it is an IDENTITY column, or NULL if the column allows it. If none of these apply, the insert fails with "Cannot insert the value NULL".

FWhat does SET IDENTITY_INSERT do?concept

It lets you insert your own values into an IDENTITY column for one table at a time. It is used for seed data that needs fixed Ids, or when copying data between databases. You must list the Id column, and you should turn it off right after the insert.

MWhy is a set-based insert faster than inserting rows one at a time in a loop?concept

A set-based statement inserts all rows in one operation, so SQL Server plans it once, writes the log efficiently, and avoids a round trip per row. A loop runs a separate statement, and often a separate commit, for every row. The SMS generator inserts 600,000 attendance rows in seconds this way.

MWhat is GENERATE_SERIES, and how did people generate numbers before SQL Server 2022?concept

GENERATE_SERIES(start, stop) returns one row per number in a range, which you can turn into generated rows. Before SQL Server 2022, developers used a permanent numbers table, a recursive CTE, or cross joins of system views to produce the same list of numbers.

MWhy does the bulk data script use one transaction with SET XACT_ABORT ON?concept

It makes the load all or nothing. With XACT_ABORT ON, any error rolls back the whole transaction, so you never end up with students but no enrollments. Combined with the "already exists" check at the top, the script can simply be run again after a failure.

SWhy test with 10,000 students when the sample school has only 12?scenario

With 12 rows every query is instant, so slow designs stay hidden until production. A realistic volume shows missing indexes, queries that return too many rows, and slow reports during development, when they are cheap to fix.

How to answer:

Give a concrete SMS example: a class report that scans every attendance row is invisible at 36 rows and obvious at 600,000. Describe how you size test data from the real school's numbers, and note that volume tests run on dedicated test databases, not on developers' shared servers.

SWhat is the difference between seed data and test data, and where does each run?design

Seed data is part of the product, such as roles, classes, and subjects, and runs in every environment, including production. Test data, such as generated students, runs only in development and test. Mixing them puts fake students into a real school or leaves production without required lookup rows.

How to answer:

Define both, give SMS examples of each, and describe how deployment keeps them apart: separate scripts or folders, and pipeline steps that run test data only in non-production environments. Mention keeping seed data re-runnable so redeploys are safe.

AHow do you create realistic test data at scale without using production data?design

Generate it from rules: numbers become names, dates, and statuses through repeatable formulas, with realistic distributions such as about 88 percent attendance. It is safe, repeatable, and sized to match real volumes. If production data must be used, it is masked or anonymized first, never copied as is.

How to answer:

Explain why production copies are risky (personal data, access control, compliance). Describe a generator's qualities: deterministic, realistic distributions, correct relationships, and fast set-based loading. Discuss the trade-off: generated data can miss rare real-world cases, so add known edge cases deliberately.

Querying basics

FIn what order does SQL Server process the clauses of a SELECT query?concept

Logically: FROM (and joins), WHERE, GROUP BY, HAVING, SELECT, ORDER BY, then TOP. That is why a column alias defined in SELECT cannot be used in WHERE, but can be used in ORDER BY.

FWhy does WHERE Occupation = NULL return no rows?concept

NULL means unknown, and comparing anything with unknown gives unknown, which is never true. So = NULL matches nothing, even rows that are NULL. Use IS NULL or IS NOT NULL instead.

FWhat do the wildcards % and _ mean in LIKE?coding

% matches any text of any length, including none, and _ matches exactly one character. LastName LIKE N'Sh%' matches Sharma and Sheikh; LIKE '_A' matches any two-character value ending in A.

MWhy should TOP always be used with ORDER BY?concept

Without ORDER BY, SQL Server returns whichever rows it reaches first, and that can change between runs, after an index change, or under load. TOP (3) ... ORDER BY DateOfBirth DESC always returns the three youngest students.

MWhy is SELECT * discouraged in application code?concept

It returns columns the code does not need, which wastes network and memory and can stop SQL Server from using a narrower index. It also changes silently when someone adds a column, which can break code that reads columns by position. List the columns you need.

MHow do you safely run an UPDATE or DELETE on important data?coding

Run a SELECT with the exact WHERE first and check the rows. Then start a transaction, run the change with the same WHERE, check @@ROWCOUNT and the data, and only then COMMIT; otherwise ROLLBACK.

SSomeone ran an UPDATE without a WHERE clause on production. What do you do?scenario

Stop further changes to that table, find out exactly what changed and when, and restore the correct values: from a backup restored to a separate database, from audit data, or from a point-in-time restore. Communicate early with the business. Afterwards, change the process so it cannot happen again.

How to answer:

Give a calm sequence: contain, assess, recover, communicate, prevent. Explain the recovery options and their trade-offs (restoring the whole database loses later work, so restore a copy and repair only the affected rows). Close with prevention: reviewed scripts, transactions, and limited write access to production.

SWhy can a search with LIKE N'%sharma%' be slow on a large table?concept

A pattern that starts with % cannot use an index seek, because the matching text could be anywhere in the value; SQL Server has to scan every row. A pattern like N'Sharma%' can seek. For true "contains" search on large tables, use full-text search or a search index.

How to answer:

Explain index seeks vs scans in one sentence, then show the two patterns. Discuss the options for a student search screen: starts-with search, full-text search, or a separate search service, and the cost of each.

AHow would you design the process for data fixes on a production database?design

Data fixes are written as scripts, reviewed by a second person, tested on a copy of production, and run by the release process with a transaction and row-count checks. The script and its result are stored, so every change is traceable. Nobody types changes directly into production.

How to answer:

Describe the workflow (request, script, review, test, approved run, record) and the controls (permissions, transactions, expected row counts, backups). Mention the trade-off: urgent fixes take minutes longer, which is cheap compared with one bad manual update.

Joins

FWhat is the difference between INNER JOIN and LEFT JOIN?concept

INNER JOIN returns only rows that match on both sides. LEFT JOIN returns every row from the left table, and fills the right table's columns with NULL when there is no match. Every teacher with their class (LEFT) shows teachers who are not class teachers; INNER would hide them.

FWhat is a join condition, and what usually goes in it?concept

The join condition, written after ON, says which rows of the two tables belong together. It is usually a foreign key equal to the primary key it references, such as ON e.StudentId = s.Id.

FWrite a query that lists the students of Class 10-A for the current year.coding

Join Students to Enrollments, then to Sections and AcademicYears, and filter on the class, the section name, and IsCurrent = 1, ordered by roll number. Four tables, each joined on its foreign key.

MWhy does adding a join sometimes multiply the number of rows?concept

If each row on the left matches several rows on the right, the left row appears once for each match. Joining 12 students to their guardians gives 24 rows, because each has two. Totals calculated after such a join are multiplied too.

MWhat is a self join? Give an example.coding

A self join joins a table to itself using two aliases. To find students who share a guardian, join StudentGuardians to itself on the same GuardianId, with a condition like sg2.StudentId > sg1.StudentId so a student does not match themselves.

MWhy does a condition on the right table belong in the ON clause of a LEFT JOIN, not in WHERE?concept

WHERE runs after the join. A condition there on the right table removes the rows where that table is NULL, which turns the LEFT JOIN into an INNER JOIN. In the ON clause, it only limits which right rows can match, and unmatched left rows are kept.

SA fee report total is exactly double what it should be. How do you find the cause?scenario

Doubled totals almost always come from a one-to-many join added after the data was already at the right level. Remove joins one at a time and watch the row count, or count rows per key to find the join that matches twice. Then aggregate before joining, or join only what the report needs.

How to answer:

Show a systematic method (compare row counts with a known number, isolate the join), then the fix (pre-aggregate in a CTE). Use the SMS example of joining payments to guardians. Mention adding a test that checks the total against a simpler query.

SWhen would you use FULL JOIN or CROSS JOIN in a real system?concept

FULL JOIN compares two lists where either side can have rows the other lacks, such as reconciling an imported fee file with the payments table. CROSS JOIN builds every combination, such as creating exam papers for every class and subject. Both are rare in daily screens.

How to answer:

Give one concrete SMS use for each, and say how you keep CROSS JOIN results under control (filter both inputs first, check the expected row count). Mention that the bulk generator in Lesson 15 uses CROSS JOIN deliberately.

AA report needs eight joins and runs slowly every morning. Would you keep the joins or build a reporting table?design

First check whether the joins are the real problem: missing indexes on the join columns are the usual cause. If the report is still too slow, or many reports repeat the same joins, a reporting table or indexed view refreshed on a schedule can serve them, accepting slightly delayed data.

How to answer:

Compare the options on freshness, cost, and complexity: tuned joins (always fresh), indexed views (fresh, slower writes), and scheduled reporting tables (fast reads, delayed data). Make the decision from measured timings and how fresh the report must be.

Aggregation

FWhat is the difference between WHERE and HAVING?concept

WHERE filters rows before they are grouped, and cannot use aggregates. HAVING filters groups after GROUP BY, so it can use aggregates, such as HAVING COUNT(*) < 5 to find small sections.

FWhat are the main aggregate functions?concept

COUNT counts rows or values, SUM adds them, AVG averages them, and MIN and MAX return the smallest and largest. With GROUP BY, each returns one value per group, such as students per section or fees per class.

FWhy does a query fail with 'column is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause'?concept

Every column in SELECT must either be in GROUP BY or be inside an aggregate. Otherwise one group could have several values for that column, and SQL Server cannot choose one. Add the column to GROUP BY or aggregate it.

MWhat is the difference between COUNT(*), COUNT(column), and COUNT(DISTINCT column)?concept

COUNT(*) counts every row. COUNT(column) counts rows where that column is not NULL, so absent students without marks are skipped. COUNT(DISTINCT column) counts different values. Four 10-A Science papers give 4, 3, and 1 respectively.

MHow do you count only some rows inside a GROUP BY query?coding

Put a CASE inside SUM: SUM(CASE WHEN Status IN ('Present', 'Late') THEN 1 ELSE 0 END) adds 1 for each matching row and 0 for others. Divided by COUNT(*) and multiplied by 100.0, it gives an attendance percentage per student.

MWhy does 100 * 2 / 3 give 66 instead of 66.67 in SQL Server?concept

When both sides of a division are whole numbers, SQL Server returns a whole number and drops the fraction. Make one side decimal, for example 100.0 * 2 / 3, or CAST a value to DECIMAL, to keep the fraction.

SThe class average looks too high because absent students are left out. How do you handle it?scenario

AVG skips NULLs, so absent students do not count. That is usually right, but the school must decide the rule. If absent should count as zero, use AVG(ISNULL(MarksObtained, 0)); if not, show the number of papers averaged next to the average so readers know.

How to answer:

Explain how aggregates treat NULL, then turn it into a business decision with the school. Show both SQL forms. Recommend documenting the definition with the report so every report uses the same rule.

STwo reports show different attendance percentages for the same class. How do you resolve it?scenario

Compare the definitions first: which statuses count as present, which dates are included, and whether deleted or transferred students are counted. Then recompute the number by hand from raw rows. Agree one definition with the school and make both reports use it.

How to answer:

Show that you treat it as a definitions problem before a SQL problem. Walk through the checks, reconcile with raw counts, and close with prevention: one shared, documented definition, ideally in one view used by every report.

AThe principal's dashboard aggregates millions of rows on every page load. How would you redesign it?design

Pre-compute the numbers: a summary table updated as data changes or on a short schedule, or an indexed view that SQL Server keeps up to date. The dashboard then reads a few rows instead of millions, at the cost of extra work on writes or slightly delayed numbers.

How to answer:

Quantify the load first (rows scanned, page loads per minute). Compare indexed views, summary tables, and caching on freshness, write cost, and complexity. Choose based on how fresh the principal really needs the numbers to be.

Subqueries and CTEs

FWhat is a subquery?concept

A subquery is a query inside another query, in brackets. It can return one value (used with = or >), a list (used with IN), or be used with EXISTS to test whether any row matches.

FWhat is a CTE?concept

A CTE (Common Table Expression) is a named query written with WITH name AS ( ... ) before a statement. That statement can use the name like a table. It makes long queries readable as steps, and it exists only for that one statement.

FFind the students who scored above their section's average.coding

Compare each mark with a subquery that returns the average for the same paper and section: WHERE m.MarksObtained > (SELECT AVG(MarksObtained) FROM dbo.Marks WHERE ...). In 10-A Unit Test 1 Mathematics, the average is 84.75, so Meera, Aarav, and Diya qualify.

MWhy can NOT IN return no rows at all, and what should you use instead?concept

If the subquery's list contains a NULL, x NOT IN (...) is unknown for every row, because "not equal to NULL" is never true. So the query returns nothing. Use NOT EXISTS, which is not affected by NULLs, or filter NULLs out inside the subquery.

MWhat is the difference between IN and EXISTS?concept

IN checks whether a value is in a list returned by the subquery. EXISTS checks whether the subquery returns any row at all, and can stop at the first match. For positive checks they often perform the same; for negative checks, NOT EXISTS is safer than NOT IN because of NULLs.

MWhat is a correlated subquery?concept

A correlated subquery uses a column from the outer query, so it is evaluated for each outer row. Example: each student's last attendance date with (SELECT MAX(a.AttendanceDate) FROM dbo.AttendanceRecords AS a WHERE a.EnrollmentId = e.Id).

SWrite a query for invoices that still have money due, with the balance.coding

In a CTE, sum the payments per invoice. Then left join the invoices to it, compute total minus discount minus ISNULL(paid, 0), and keep rows where that is above zero. Summing first avoids multiplied totals, and the left join keeps invoices with no payments.

How to answer:

Write it in two steps aloud, explaining why each part exists (CTE to aggregate, LEFT JOIN for unpaid invoices, ISNULL for NULL sums). Mention edge cases: deleted payments, discounts, and cancelled invoices, and how you would test the result against one known invoice.

SA nightly job using NOT IN suddenly sends no reminders at all. What happened?scenario

Most likely a NULL appeared in the column the NOT IN subquery returns, so the condition became unknown for every row and nothing qualified. Rewrite it with NOT EXISTS, fix or explain the NULL data, and add an alert when a reminder job processes zero rows.

How to answer:

Diagnose from the symptom (zero rows, not an error), explain the three-valued logic briefly, then fix and prevent: NOT EXISTS, a data check, and monitoring that treats "zero processed" as suspicious.

AWhen would you choose a CTE, a temporary table, or a view for a multi-step report?design

A CTE for readable steps inside one statement. A temporary table when an intermediate result is reused several times, is large, or benefits from its own index. A view when many queries and reports need the same logic. Each adds reuse or speed at the cost of more objects to manage.

How to answer:

Compare scope (one statement, one session, permanent), reuse, and performance. Use SMS examples for each: a report card CTE, a temp table for a year-end calculation, a view for "current enrollments". Mention measuring before switching for speed.

Window functions

FWhat is the difference between ROW_NUMBER, RANK, and DENSE_RANK?concept

All three number rows in order. ROW_NUMBER always gives different numbers, even for ties. RANK gives ties the same number and then skips (1, 2, 3, 3, 5). DENSE_RANK gives ties the same number without gaps (1, 2, 3, 3, 4).

FHow is a window function different from GROUP BY?concept

GROUP BY collapses each group into one row. A window function calculates across a group of rows but keeps every row, so you can show each student with their rank or the section average next to their mark.

FWhat does PARTITION BY do in an OVER clause?concept

It splits the rows into groups, and the window function restarts for each group. RANK() OVER (PARTITION BY SectionId ORDER BY Total DESC) ranks students within their own section, starting at 1 in every section.

MHow do you remove duplicate rows from a table using ROW_NUMBER?coding

Number the rows within each group of duplicates with ROW_NUMBER() OVER (PARTITION BY the duplicate columns ORDER BY a tie-breaker) in a CTE. Rows numbered 1 are kept; delete or ignore the rest.

MHow do you calculate a running total in SQL Server?coding

Use SUM(Amount) OVER (ORDER BY PaidOn, ReceiptNumber ROWS UNBOUNDED PRECEDING). Each row gets the total of all rows up to it. A unique ORDER BY and the explicit ROWS frame make the result predictable and fast.

MWhat do LAG and LEAD do?concept

LAG(column) returns the value from the previous row in the window, and LEAD(column) from the next row. They compare a row with its neighbours, such as this exam's marks against the previous exam's. The first row's LAG is NULL.

SWrite a query for the top 3 students in every section.coding

In a CTE, compute each student's total, then add ROW_NUMBER() OVER (PARTITION BY Section ORDER BY Total DESC, AdmissionNumber). In the outer query, keep rows numbered 1 to 3. Use RANK instead if tied students must both appear.

How to answer:

Write the two-step pattern and explain why the filter must be outside (window functions are not allowed in WHERE). Ask about the tie rule before choosing the function, and mention the tie-breaker that keeps results stable.

SA page loads 50,000 rows into C# only to rank them and show the top 3 per group. How would you improve it?scenario

Move the ranking into SQL with a window function and return only the rows the page shows. The database does it in one pass with the data already there, and the network, memory, and page time drop sharply.

How to answer:

Measure first (rows transferred, page time), then show the window-function rewrite and the expected gain. Discuss the trade-off: logic in SQL is less visible to C# developers, so keep it in a named view or procedure with tests.

AShould rankings and running totals be calculated in the database or in application code?design

For large data sets, in the database: it avoids moving rows and uses set-based processing. For small results that the screen already holds, or rules that change often and need unit tests in C#, application code can be simpler. Keep one place responsible for each calculation.

How to answer:

Weigh data volume, network cost, testability, and who maintains the logic. Give SMS examples on both sides (prize lists over 10,000 students in SQL; re-sorting 40 rows on a screen in code). Stress consistency: one calculation, one place.

Views and functions

FWhat is a view?concept

A view is a saved SELECT with a name. It stores no data; every time you query it, SQL Server runs its query against the real tables. Views hide joins and filters, such as vw_CurrentEnrollments hiding four joins and the soft-delete filter.

FWhat is the difference between a scalar function and a table-valued function?concept

A scalar function returns one value and is used in SELECT or WHERE, such as dbo.fn_GetGrade(92). A table-valued function returns a table and is used in FROM, such as dbo.fn_GetSectionResults(1, 19). An inline table-valued function is like a view that takes parameters.

FWhy use a view to hide soft-deleted rows?concept

So the IsDeleted = 0 filter is written once. Every report and API that reads the view automatically leaves deleted students out, and nobody can forget the filter. In the SMS, soft-deleting Meera drops the 10-A count from 4 to 3 through the view.

MWhat is the difference between a view and an inline table-valued function?concept

Both are saved queries used in FROM. A view takes no parameters, while an inline table-valued function does, such as an exam and section. SQL Server expands both into the calling query, so both perform like the query written out in full.

MWhy can a scalar function make a query slow?concept

It runs once for every row it is applied to, and when used on a column in WHERE, it hides that column from indexes. SQL Server 2019 and later can inline simple scalar functions, but functions that read tables or use loops often cannot be inlined.

MCan you insert or update through a view?concept

Yes, if the change affects one base table and the view has no DISTINCT, GROUP BY, or aggregates. Views with joins usually cannot accept changes to more than one table. In the SMS, views are for reading; changes go through tables or procedures.

SA report using a scalar function over 2 million rows takes 40 minutes. How do you fix it?scenario

Look at what the function does. If it reads tables, rewrite that logic as a join or an inline table-valued function so SQL Server processes all rows as one set. Compare the plans and timings before and after; this kind of rewrite often turns minutes into seconds.

How to answer:

Explain the row-by-row cost and why the optimizer cannot see inside a non-inlined function. Describe the rewrite and how you would prove it with logical reads and duration. Mention checking whether SQL Server's scalar UDF inlining applies first.

SHow can views be used as a security boundary?design

Grant reporting users SELECT on views only, never on the tables. The view exposes only the columns and rows they may see, and because the view and tables have the same owner, SQL Server does not check table permissions (ownership chaining). The tables stay private.

How to answer:

Combine the design (views as the public shape of the data) with the permission model (GRANT on views, nothing on tables). Use the SMS reports role. Note the limit: a view is not row-level security per user; for that, use filters or Row-Level Security policies.

AWhen would you use an indexed view, and what does it cost?design

When a frequently run aggregate over large tables is too slow and must be up to date, such as daily attendance totals. The indexed view stores its result and SQL Server maintains it on every change to the base tables, so reads are fast but writes become slower, and strict rules apply.

How to answer:

Present it as one option among summary tables, caching, and better indexes. Weigh freshness against write cost, and mention the restrictions (schema binding, no outer joins). Decide from measured numbers on the real workload.

Stored procedures

FWhat is a stored procedure?concept

A stored procedure is a named block of T-SQL saved in the database, with parameters. It can read and change data and use transactions. The SMS uses usp_RecordFeePayment to check, save, number, and update a payment in one call.

FWhat is the difference between a stored procedure and a function?concept

A procedure can change data and use transactions, and is called with EXEC. A function cannot change data, and is used inside a query, returning one value or a table. Use procedures for business actions and functions for calculations and reusable reads.

FWhat is an OUTPUT parameter?concept

A parameter that sends a value back to the caller. usp_RecordFeePayment returns the new receipt number through @ReceiptNumber OUTPUT, and the caller passes a variable with the OUTPUT keyword to receive it.

MWhy use SET NOCOUNT ON in a stored procedure?concept

It stops SQL Server from sending a "rows affected" message after every statement. The application does not need them, they add network traffic, and some client libraries can confuse them with result sets.

MHow do stored procedures protect against SQL injection, and when can they still be vulnerable?concept

Parameters are treated as values, never as code, so input like '; DELETE ... is just text. A procedure is still vulnerable if it builds dynamic SQL by joining strings with input. Dynamic SQL must pass values through sp_executesql parameters.

MWhy use a SEQUENCE instead of MAX(...) + 1 to number receipts?concept

Two sessions running MAX + 1 at the same time can read the same maximum and produce the same number. A sequence hands out each number exactly once, without locking the table. Numbers used in rolled-back transactions are not returned, so gaps can appear.

STwo payments for the same invoice arrive at the same moment. How does usp_RecordFeePayment stay correct?scenario

It reads the invoice WITH (UPDLOCK) inside its transaction. The second payment waits until the first commits, then sees the updated balance, so both cannot pass the balance check. The receipt numbers come from a sequence, so they never collide.

How to answer:

Describe the race condition first (both read the same balance), then the fix (lock the row you will change, early), and the guarantee it gives. Mention the cost: payments for the same invoice are serialized, which is acceptable because they are rare.

SHow do you change a stored procedure that the API depends on without breaking it?design

Treat parameters and result columns as a contract. Use CREATE OR ALTER so permissions are kept, add new parameters at the end with defaults, and do not rename or remove result columns that callers read. Deploy the database change before the application change that uses it.

How to answer:

Explain backward compatibility, the deployment order, and how you test both old and new callers. Mention versioned procedure names as a last resort for breaking changes.

AShould business logic live in stored procedures or in application code?design

Data-heavy, transactional steps that must be atomic, such as recording a payment, fit procedures well. Workflows, validation messages, integrations, and logic that needs unit tests fit application code better. Most systems use both, with a clear rule for which goes where.

How to answer:

Avoid absolutes. Weigh testability, deployment, team skills, performance, and reuse across channels. Give SMS examples on both sides and describe the agreed boundary your team would write down.

Triggers

FWhat is a trigger?concept

A trigger is code attached to a table that SQL Server runs automatically when rows are inserted, updated, or deleted. It runs inside the same transaction, so it can refuse a change with an error or record it in another table.

FWhat are the inserted and deleted tables in a trigger?concept

They are temporary tables with the same columns as the real table. inserted holds new rows (after an insert or update), and deleted holds old rows (after an update or delete). For an update, joining them shows each row before and after.

FWhy does the SMS use a trigger for 'marks not above the maximum' instead of a CHECK constraint?concept

The maximum is in ExamSubjects, another table, and a CHECK constraint can only see the row being saved. The trigger joins inserted to ExamSubjects and throws error 50001 if any mark is too high.

MHow many times does a trigger fire for an UPDATE that changes 500 rows?concept

Once. Triggers fire per statement, with all 500 rows in inserted and deleted. Code that assumes a single row, such as assigning a column to a variable, silently handles only one of them; trigger code must be set-based.

MWhat happens when a trigger throws an error?concept

The statement that fired it fails, and its transaction is rolled back, including any rows the trigger itself wrote. In the SMS, updating two marks where one is 105 fails as a whole: both marks keep their old values.

MHow does the audit trigger know which user made a change?concept

The API stores the logged-in user's Id in SESSION_CONTEXT for the connection, with sp_set_session_context. The trigger reads it with SESSION_CONTEXT(N'UserId'), so it knows the user without the API passing it to every statement.

SSaving marks became slow after someone added a trigger. What do you check?scenario

Read the trigger: loops, cursors, queries without indexes, or calls to other databases or services run inside every save. Check the plan of the trigger's statements and the wait types during saves. Rewrite it set-based and move any external work out of the transaction.

How to answer:

Show that triggers are part of the write path. Describe how you would measure (plans, duration with and without the trigger) and the usual culprits. End with a rule: triggers only check and record.

SHow would you choose between a constraint, a trigger, and a stored procedure for a business rule?design

Use a constraint when the rule concerns one row and is always true. Use a procedure for a multi-step business action. Use a trigger only when the rule needs other tables and must hold for every way data is written, such as imports and manual fixes.

How to answer:

Give the decision order (constraint, then procedure, then trigger) and an SMS example for each. Mention the costs of triggers: hidden behaviour, write overhead, and testing effort.

AHow would you design auditing for a system that must keep every change for 7 years?design

Record old and new values with who and when for the tables that matter, using triggers, temporal tables, or change data capture. Store audit data so it cannot be edited by the application, partition or archive it by date, and plan its size, retention, and access.

How to answer:

Compare the options: triggers (flexible, custom), system-versioned temporal tables (automatic history per table), and change data capture (log-based, for downstream use). Cover storage growth, query needs, security, and how long data must be kept.

Transactions

FWhat is a transaction?concept

A group of changes that succeed together or fail together. BEGIN TRANSACTION starts it, COMMIT makes every change permanent, and ROLLBACK undoes them all. Recording a payment and updating the invoice status is one transaction.

FWhat does ACID stand for?concept

Atomicity (all or nothing), Consistency (rules hold before and after), Isolation (others do not see half-done work), and Durability (committed changes survive a crash). Together they describe what a database transaction guarantees.

FWhat is autocommit mode?concept

SQL Server's default: without BEGIN TRANSACTION, each statement is its own transaction and is committed as soon as it succeeds. Two related statements run this way are not protected; if the second fails, the first stays saved.

MInside a transaction, the second of two statements fails. Is the first one undone?concept

Not by default. SQL Server undoes only the failed statement; the transaction stays open with the first change in it, and a later COMMIT saves it. Use TRY...CATCH with ROLLBACK, or SET XACT_ABORT ON, so any error undoes everything.

MWhat does SET XACT_ABORT ON do, and why use it?concept

With it on, any run-time error rolls back the whole transaction and stops the batch. It guarantees that a failure never leaves a half-done transaction, even when a CATCH block is missing or a client times out. Procedures that change data should use it.

MWrite the standard TRY...CATCH pattern for a transaction.coding

BEGIN TRY BEGIN TRANSACTION; ...changes...; COMMIT TRANSACTION; END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; THROW; END CATCH;. The check avoids an error when no transaction is open, and THROW; passes the original error to the caller.

SDoes SQL Server support nested transactions?concept

Not really. Each BEGIN TRANSACTION increases @@TRANCOUNT, and an inner COMMIT only decreases it; nothing is saved until the outermost COMMIT. A ROLLBACK anywhere undoes everything and sets the count to 0. Savepoints are the only way to undo part of a transaction.

How to answer:

Explain @@TRANCOUNT with the 2, 1, 0 example, then the consequence: a procedure that rolls back destroys its caller's transaction. Show how callers should check @@TRANCOUNT after an error, and mention savepoints for partial undo.

SUsers say saving 'hangs' every afternoon. You suspect an open transaction. How do you find it?scenario

Run DBCC OPENTRAN in the database to see the oldest open transaction and its session, and query sys.dm_exec_requests for blocked sessions and who blocks them. Often it is an SSMS window with an uncommitted change, or an application path that never commits. Close or kill it, then fix the cause.

How to answer:

Give the diagnosis steps with the exact tools, then the decision (contact the owner before killing a session), and the prevention: short transactions, XACT_ABORT, and alerts on long-running transactions.

AA business action spans the database and an external payment service. How do you keep them consistent?design

A database transaction cannot include an external service. Record the intent first in the database, call the service with an idempotency key, then record the result; a background job retries or reconciles anything left pending. The design accepts brief inconsistency and always ends in a known state.

How to answer:

Explain why distributed transactions are avoided, then describe the pattern (outbox or pending-state plus reconciliation). Use the SMS online payment as the example, and cover retries, idempotency, and monitoring.

Locking and isolation

FWhat is the difference between a shared lock and an exclusive lock?concept

A shared lock is taken for reading; many sessions can hold it at once. An exclusive lock is taken for changing data; only one session can hold it, and it blocks other writers and, by default, readers. Exclusive locks last until the transaction ends.

FWhat is SQL Server's default isolation level?concept

READ COMMITTED. Readers see only committed data, and wait for writers that hold locks on the rows they need. It prevents dirty reads but still allows non-repeatable reads and phantoms.

FWhat is a deadlock?concept

Two sessions each hold a lock the other needs, so neither can continue. SQL Server detects it within seconds, chooses one session as the victim, rolls it back, and returns error 1205, letting the other finish.

MWhat is a dirty read, and which setting allows it?concept

A dirty read sees a change that another transaction has not committed and may roll back. READ UNCOMMITTED and the NOLOCK hint allow it. In the SMS demo, a NOLOCK read returned a phone number that was rolled back a moment later.

MHow do you find which session is blocking another?coding

Query sys.dm_exec_requests for rows where blocking_session_id <> 0, joined to sys.dm_exec_sql_text for the waiting query. It shows who waits, who blocks, the wait type such as LCK_M_S, and for how long.

MWhat is Read Committed Snapshot Isolation (RCSI)?concept

A database setting that makes normal READ COMMITTED reads use the last committed version of each row instead of waiting for writers' locks. Readers stop blocking on writers, and still never see uncommitted data. The cost is row versions kept in tempdb.

SUsers get deadlock errors when saving attendance and fees. How do you reduce them?scenario

Capture the deadlock details (from the system_health session) to see which statements and resources are involved. Then make every code path touch tables and rows in the same order, keep transactions short, add indexes so fewer rows are locked, and retry error 1205 a few times.

How to answer:

Start from evidence (the deadlock graph), then apply the prevention techniques in order of impact. Explain why retrying is still needed, and why NOLOCK is not a fix.

SA developer added WITH (NOLOCK) to every report query to stop blocking. What is your response?scenario

NOLOCK can return uncommitted rows, skip rows, or read rows twice when pages move, so reports can show wrong numbers. Find the real cause of the blocking, usually long transactions or missing indexes, and consider RCSI so reports read committed versions without waiting.

How to answer:

Acknowledge the pain, explain the correctness risks with a concrete example, and offer better options. Mention where NOLOCK is acceptable: rough monitoring queries where accuracy does not matter.

AHow would you choose isolation settings for an SMS serving 1,000 schools?design

Turn on RCSI so reads do not block on writes, keep READ COMMITTED as the default, and use stronger locking only where needed, such as UPDLOCK on an invoice during payment. Test under realistic concurrency, and monitor blocking and deadlocks in production.

How to answer:

Weigh correctness, concurrency, and tempdb cost. Explain why SERIALIZABLE everywhere does not scale, and why targeted locking for money operations does. Mention load testing at the 8:45 AM peak and monitoring.

Indexes

FWhat is an index?concept

A sorted structure that lets SQL Server find rows without reading the whole table, like the index at the back of a book. In the SMS, an index on AttendanceDate cut one day's attendance query from 3,351 page reads to 38.

FWhat is the difference between a clustered and a nonclustered index?concept

The clustered index is the table itself, stored in key order; there is only one. A nonclustered index is a separate sorted copy of some columns with a pointer to the row; a table can have many. Primary keys are clustered by default.

FWhat is the difference between an index seek and an index scan?concept

A seek jumps straight to the matching values in a sorted index and reads few pages. A scan reads the whole index or table. Scans are fine for small tables or when most rows are needed, but a scan on a big table for a few rows usually means a missing or unusable index.

MWhat is a covering index, and what does INCLUDE do?concept

A covering index contains every column a query needs, so no key lookups to the table are required. INCLUDE adds columns to the index's leaf level without sorting by them, such as INCLUDE (Status) on the attendance date index.

MWhy does the order of columns in a multi-column index matter?concept

SQL Server can seek only on the leading column or columns. An index on (ExamSubjectId, EnrollmentId) helps a search by paper, but not a search by enrollment alone, which is why the SMS needed a separate index starting with EnrollmentId.

MWhat is the cost of adding indexes?concept

Every insert, update, and delete on the indexed columns must also update each index, so writes get slower, and each index takes storage and memory. Add indexes for frequent, measured queries, and drop indexes that are never used.

SThe daily attendance report is slow. Walk through how you would decide which index to add.scenario

Measure the query with SET STATISTICS IO and the actual plan, and find the scan on the big table. Index the filtered column first, here AttendanceDate, and include the columns the query reads, here Status. Measure again: in the SMS, reads dropped from 3,351 to 38.

How to answer:

Follow measure, analyze, change, measure. Explain the column choice (filter first, include the rest) and confirm the plan changed to a seek. Mention checking the write cost on a busy table.

SA table has 23 indexes and inserts are slow. What do you do?scenario

Check sys.dm_db_index_usage_stats over a representative period to find indexes with many updates and no reads, and look for indexes that duplicate or overlap others. Drop or merge them after review, keeping the ones that serve important queries.

How to answer:

Show a data-driven clean-up: usage statistics, overlap analysis, and agreement with the team. Mention that usage stats reset on restart, so measure over a long enough period, and keep indexes that support constraints.

AHow do you plan an indexing strategy for a new system?design

Start with primary keys, unique constraints, and indexes on foreign keys used in joins. Then add indexes for the most frequent and most important queries, tested with realistic data volumes. Review usage and missing-index data after launch, and maintain indexes and statistics on a schedule.

How to answer:

Describe the lifecycle: design-time basics, query-driven additions, load testing, and production review. Balance read speed against write cost per table, such as the busy attendance table versus rarely written masters.

Execution plans

FWhat is an execution plan?concept

The step-by-step recipe SQL Server chooses to run a query: which indexes to read, in what order, and how to join the results. You read it in SSMS to see why a query is slow.

FWhat is the difference between an estimated and an actual execution plan?concept

The estimated plan is built without running the query and shows guessed row counts. The actual plan is captured while the query runs and adds real row counts. Use the actual plan when you can, because big gaps between estimated and actual rows point to problems.

FWhat does SET STATISTICS IO ON show, and why is it useful?concept

It reports the logical reads (8 KB pages read) for each table a query touches. Logical reads do not change with caching, so they are a fairer before-and-after measure than duration.

MWhat does SARGable mean? Give an example of a non-SARGable condition.concept

A SARGable condition lets SQL Server seek in an index. YEAR(AttendanceDate) = 2026 is not SARGable because the function hides the column; in the SMS it read 1,567 pages, while AttendanceDate = '2026-07-01' read 38. Compare the bare column, using a date range if needed.

MWhat is an implicit conversion, and how does it hurt performance?concept

When a value's type differs from the column's, SQL Server converts one of them. If it must convert the column, as with a VARCHAR column compared to an NVARCHAR value, it cannot seek. In the SMS, N'ADM-2017-0001' caused a scan of 39 reads; 'ADM-2017-0001' was a 4-read seek.

MWhat is a key lookup, and why might SQL Server ignore your index?concept

A key lookup fetches columns missing from a nonclustered index, one row at a time. For many rows, SQL Server decides a full scan is cheaper: 668 matching Sharmas led to a scan of 126 reads. A covering index with INCLUDE turned it into a 6-read seek.

SA query ran in 1 second yesterday and takes 40 seconds today. Nothing was deployed. What do you check?scenario

Check for blocking first, then compare today's plan with the old one, using Query Store if it is on. Common causes are parameter sniffing (a plan built for unusual values), outdated statistics after a big data load, and data growth past a tipping point.

How to answer:

Give a calm, ordered checklist: blocking, plan change, statistics, data volume. Explain how you would prove the cause, then the fix, such as updating statistics, forcing a good plan, or adjusting an index. Mention measuring after the fix.

SWhat is parameter sniffing, and how do you deal with it?concept

SQL Server builds a procedure's plan for the first parameter values it sees and reuses it. That plan can be poor for very different values, such as a tiny section versus a huge one. Fixes include better indexes, OPTION (RECOMPILE) for a specific query, or forcing a good plan with Query Store.

How to answer:

Explain that sniffing is normally helpful, then show when it hurts with the SMS class list example. Compare fixes by cost: RECOMPILE costs CPU per call, while a better index helps every value.

AHow would you set up ongoing query performance monitoring for a production database?design

Turn on Query Store to keep plan and runtime history, and track the top queries by total CPU and reads. Alert on regressions, blocking, and deadlocks, and review the top queries regularly, tuning with the measure, change, measure method.

How to answer:

Describe the tools (Query Store, DMVs, alerts), the routine (weekly top-N review), and the ownership (who acts on alerts). Link it to business outcomes, such as the attendance peak at the start of the school day.

Security and backup

FWhat is the difference between a login and a user in SQL Server?concept

A login is server-level and controls who can connect. A user is database-level, mapped to a login, and holds permissions inside one database. For example, SchoolApiLogin connects, and SchoolApiUser works in SchoolDb.

FWhat do GRANT, DENY, and REVOKE do?concept

GRANT allows an action, DENY forbids it, and REVOKE removes an earlier grant or deny. DENY always wins over GRANT, which is how a role can delete in general but never delete from Students.

FWhat are the full, differential, and transaction log backup types?concept

A full backup copies the whole database. A differential copies changes since the last full backup. A log backup copies changes since the last log backup and allows restoring to a point in time.

MWhat is the difference between the SIMPLE and FULL recovery models?concept

SIMPLE allows no log backups, so you can restore only to the last full or differential backup. FULL needs regular log backups, or the log keeps growing, and it allows restoring to any point in time. Use SIMPLE for development and FULL for production.

MWhy should an application not connect as sa or db_owner?concept

One bug or SQL injection would then have full control, including dropping the database. Least privilege gives the application its own login and a role with only the permissions it needs, such as running procedures and changing specific tables.

MWhat are RPO and RTO?concept

RPO (Recovery Point Objective) is how much data the business can afford to lose, such as 15 minutes. RTO (Recovery Time Objective) is how long the system may be down, such as 2 hours. Together they decide the backup types and schedule.

SThe school can lose at most 15 minutes of data. Design the backup schedule and explain a restore to 10:40 AM Wednesday.scenario

Use the FULL recovery model, a full backup on Sunday night, differentials on the other nights, and log backups every 15 minutes. To restore: Sunday's full backup, Tuesday night's differential, then every log backup up to 10:40 with STOPAT.

How to answer:

Start from RPO and RTO, then derive the schedule. Walk through the restore sequence step by step, and add retention, off-site copies, and regular restore tests.

SHow do you know your backups actually work?concept

RESTORE VERIFYONLY checks that a backup file is readable, but only a real restore proves it. Restore regularly to a test server, run DBCC CHECKDB, check key row counts, and time it against the RTO.

How to answer:

Distinguish verifying a file from proving a restore. Describe an automated, scheduled restore test with results someone reviews, and mention that the course's restored copy was checked by counting students.

AHow would you protect a school database against ransomware?design

Follow 3-2-1: three copies, on two kinds of storage, one off site, plus one immutable copy that cannot be changed or deleted for a set time. Limit who can reach backup storage, use separate credentials for it, and test restores from the immutable copy.

How to answer:

Cover prevention (least privilege, patching), protection of backups (immutability, separate accounts), and recovery (tested restore plan meeting the RTO). Keep it business-focused: the school must be running again on the next school day.

Interview practice

FWrite a query to find the second-highest mark in a paper.coding

Use DENSE_RANK() OVER (ORDER BY MarksObtained DESC) and keep rank 2, or use a subquery: MAX(MarksObtained) WHERE MarksObtained < (SELECT MAX(...)). For 10-A's Mathematics marks of 95, 92, 85, and 67, both return 92.00, and DENSE_RANK handles ties and any N.

FHow do you find duplicate values in a column?coding

Group by the column and keep groups with more than one row: SELECT LastName, COUNT(*) FROM dbo.Students GROUP BY LastName HAVING COUNT(*) > 1;. To delete duplicates while keeping one, use ROW_NUMBER() partitioned by the column.

FWhat is the difference between UNION and UNION ALL?concept

UNION ALL keeps every row; UNION removes duplicates, which needs a sort or hash. In the SMS, 8 teacher and 22 guardian last names give 30 rows with UNION ALL but 19 with UNION. Prefer UNION ALL when duplicates are impossible or wanted.

MHow do you find rows in one table with no match in another?coding

Use NOT EXISTS with a correlated subquery, or a LEFT JOIN and WHERE right.Id IS NULL. Avoid NOT IN when the subquery's column can be NULL, because one NULL makes it return no rows.

MHow do you turn rows into columns, such as one column per attendance status?coding

Use conditional aggregation: SUM(CASE WHEN Status = 'Present' THEN 1 ELSE 0 END) AS Present, one expression per status, grouped by student. SQL Server's PIVOT keyword does the same, but SUM(CASE ...) is easier to read and works in every database.

MWhy is DATEDIFF(YEAR, DateOfBirth, @Date) wrong for age, and how do you fix it?coding

DATEDIFF counts year boundaries crossed, not birthdays. Someone born 23 August 2011 gets 15 on 1 July 2026, but is really 14. Subtract 1 when the birthday has not yet happened in that year.

STell me about a database you designed.scenario

In about two minutes, cover what it is, the key design choices, the rules enforced in the database, the performance work with numbers, and safety. For the SMS: 22 tables, enrollments per year, a trigger and transactional procedures, indexes cutting 3,351 reads to 38, and least-privilege roles with tested backups.

How to answer:

Use the five-part structure and give at least one measured result. Be ready for follow-ups on any part, and mention a trade-off you made and why.

SThe fee report is suddenly slow. Walk me through your answer.scenario

Restate the symptom and ask what changed, then measure: actual plan, logical reads, and blocking. List the likely causes in order, such as a plan change, outdated statistics, or a missing index after data growth. Make the smallest fix, measure again, and add monitoring.

How to answer:

Use the five-part scenario structure: symptom, measure, cause, fix, prevent. Keep each part short and concrete, naming the exact tools you would use.

AAs a lead, how would you assess a candidate's SQL skills?design

Mix a short live task on a realistic schema, a design discussion, and a scenario question. Judge how they clarify requirements, handle NULLs and ties, test edge cases, and explain trade-offs, not just whether the query runs.

How to answer:

Describe a structured, fair process: the same tasks and scoring rubric for every candidate, with expectations matched to the level. Mention watching for thinking aloud and self-correction.

Temp tables and cursors

FWhat is a temp table in SQL Server?concept

A table whose name starts with #, stored in tempdb and visible only to your session. It lives until the session ends or you drop it. You use it to save an intermediate step of a report and reuse it in later queries.

FWhat is the difference between #Name and ##Name?concept

#Name is a local temp table, visible only to the session that created it. ##Name is a global temp table, visible to every session. Reports should use local tables, so two users never share or overwrite each other's data.

FWhat is a cursor, and what are its steps?concept

A cursor reads a query's rows one at a time. The steps are DECLARE, OPEN, FETCH NEXT, a WHILE @@FETCH_STATUS = 0 loop, and finally CLOSE and DEALLOCATE.

MCompare a temp table, a table variable, and a CTE.concept

A CTE is not stored and belongs to one statement. A temp table lives in tempdb until the session ends, has statistics, and can have any index. A table variable lives for one batch, has no column statistics, and is not undone by ROLLBACK. Use temp tables for big or reused steps.

MWhy is a cursor usually slower than a set-based query?concept

A cursor runs one small query per row, each with its own overhead. A set-based query reads the data once in one plan. In the SMS, a cursor over 10,012 students took about 2.9 seconds, and one GROUP BY gave identical results in about 0.2 seconds.

MWhat happens to a table variable's rows when a transaction rolls back?concept

They stay. Table variables are not part of the transaction, so ROLLBACK does not undo them. This is useful in a CATCH block: save error details in a table variable, roll back, and then write them to a log table.

SA nightly job loops over 10,000 students with a cursor and takes 40 minutes. How do you fix it?scenario

Find what each loop iteration does, and express the whole job as a few set-based statements, using temp tables for intermediate steps. Prove the new version gives the same rows with EXCEPT, then measure. Keep a loop only for work that truly must happen one row at a time.

How to answer:

Show the method: understand, rewrite in sets, prove equality, measure. Mention SET NOCOUNT ON, testing on a copy of production-sized data, and running old and new versions side by side before switching.

SWhen is a cursor the right choice?concept

When each row must go through logic that handles one row at a time, such as calling a procedure like usp_RecordFeePayment for every payment in an uploaded file. Admin scripts that loop over databases or tables are another fair use. Use LOCAL FAST_FORWARD.

How to answer:

Avoid "never use cursors". Give the rule (if it can be one query, write one query), then real exceptions, and mention the alternative of a set-based procedure that accepts many rows.

AHow would you guide a team that writes most reports with loops and cursors?design

Set a review rule: set-based first, cursors only with a written reason. Provide patterns (temp-table steps, window functions, conditional aggregation), pair on rewriting the slowest jobs, and track their run times so the gains are visible.

How to answer:

Focus on changing habits, not one query: standards, examples, mentoring, and measurement. Mention tempdb sizing and monitoring as temp tables become more common.

MERGE and upserts

FWhat is an upsert?concept

Updating a row if it already exists and inserting it if it does not, in one operation. Loading a revised fee list, where some fees change and some are new, is an upsert.

FWhat are the three branches of a MERGE statement?concept

WHEN MATCHED (in both, usually update), WHEN NOT MATCHED BY TARGET (only in the source, usually insert), and WHEN NOT MATCHED BY SOURCE (only in the target, usually delete). Each is optional, and the statement must end with a semicolon.

FWhat is a staging table?concept

A table that holds incoming data, such as an uploaded file, before it touches the real tables. You can check and clean the data there, then apply it with a merge.

MHow do you see what a MERGE changed?coding

Add an OUTPUT clause. $action returns INSERT, UPDATE, or DELETE for each row, deleted holds the old values, and inserted the new ones. You can also send the output into a log table with OUTPUT ... INTO.

MWhat causes error 8672 in a MERGE, and how do you prevent it?concept

One target row matched more than one source row, so SQL Server would update or delete it twice. Prevent it with a primary key on the staging table, or remove duplicates before the merge.

MWhy add WITH (HOLDLOCK) to a MERGE?concept

Without it, two sessions running the same merge can both decide a row is missing and both insert it, causing a duplicate key error. HOLDLOCK keeps the range locked for the whole statement, so the second session waits.

SA teacher uploaded one section's student list and the import deleted every other section's students. What went wrong, and how do you prevent it?scenario

The merge had a WHEN NOT MATCHED BY SOURCE THEN DELETE branch on the whole table, so every row missing from the file counted as deleted. Limit the target to the rows the file covers, preview deletes before running, and require confirmation. Foreign keys and backups are the last line of defense.

How to answer:

Explain the mechanism, then the immediate recovery (restore or rebuild from backup), then prevention at several layers: scoped targets, previews, confirmation, foreign keys, and tests with a partial file.

SMERGE or UPDATE plus INSERT: which do you choose for an upsert?concept

Both work when written carefully. MERGE is shorter and can also delete, but has more traps: duplicates, scoping, and concurrency. UPDATE plus INSERT in a transaction with UPDLOCK, HOLDLOCK is longer but easier to review. Follow the team standard.

How to answer:

Compare on correctness, readability, and concurrency, and show you know the traps of each. Mention making the upsert idempotent, so a repeated import changes nothing.

ADesign a safe fee-list import for 1,000 schools.design

Upload into a staging table with keys and validation, show a preview of inserts, updates, and deletes, and require a person to confirm. Apply in a short transaction with locking hints, log every change with OUTPUT, and keep the import idempotent so retries are harmless.

How to answer:

Cover the full flow: upload, validate, preview, approve, apply, audit. Address scale (one school's import must never touch another school's rows) and recovery (undo from the change log).

JSON

FWhat is JSON, and how does SQL Server store it?concept

JSON is a text format of objects (name and value pairs), arrays, and values, used by web and mobile apps. SQL Server 2022 stores it as text in NVARCHAR(MAX); SQL Server 2025 adds a native json type.

FWhat do FOR JSON PATH and OPENJSON do?concept

FOR JSON PATH turns query results into JSON text. OPENJSON does the opposite: it turns JSON text into rows, which you can select or insert into a table.

FHow do you check whether a string is valid JSON?concept

ISJSON(@text) returns 1 for valid JSON and 0 otherwise. A trailing comma, for example, makes it return 0.

MHow do you return nested JSON, such as a student with a guardians array?coding

Use FOR JSON PATH. A dot in a column alias, like [currentClass.section], creates a nested object. A correlated subquery that ends with FOR JSON PATH creates an array. Add WITHOUT_ARRAY_WRAPPER to return a single object.

MWhat is the difference between JSON_VALUE and JSON_QUERY?concept

JSON_VALUE returns a single value, such as a number or text. JSON_QUERY returns an object or array. JSON_VALUE on an object returns NULL, which is a common surprise.

MHow do you insert rows from a JSON array?coding

Use INSERT ... SELECT ... FROM OPENJSON(@json) WITH (Column TYPE '$.path', ...). The WITH clause names each column, its type, and its path; missing properties become NULL. Paths are case-sensitive.

SThe attendance app sends one request per student and some fail on weak networks. How would you redesign it?scenario

Send the whole section as one JSON array and save it with one INSERT ... OPENJSON (or a bulk insert from C#) inside a transaction. The section is then saved completely or not at all, and the app can retry safely because the unique key prevents duplicates.

How to answer:

Explain the failure mode (partial saves), the new design (one atomic call), and the safety net (validation, constraints, unique keys for idempotent retries). Mention a clear error message for the teacher.

SWhen should data be stored as JSON instead of normal columns?concept

Use JSON for data with a varying shape that you store and return whole, such as audit details or extra settings. Use normal columns for anything you filter, join, sort, or must check with constraints.

How to answer:

Give both sides with examples, then the cost of getting it wrong: slow, unchecked filters on JSON, or many sparse columns. Mention computed columns with indexes for the occasional JSON filter.

AShould JSON for an API be built in SQL Server or in the application?design

Usually in the application: the API controls its own response format, and C# serializes objects automatically. FOR JSON is a good option for large nested reports read straight from the database, and OPENJSON for saving many rows sent in one call.

How to answer:

Weigh separation of concerns, performance, testability, and team skills. Show you would pick per case and keep one consistent default.

Temporal tables

FWhat is a temporal (system-versioned) table?concept

A table for which SQL Server automatically keeps every old version of every row in a history table. Two period columns, ValidFrom and ValidTo, record when each version was valid.

FHow do you see a table as it was at a past moment?coding

Query it with FOR SYSTEM_TIME AS OF @moment. SQL Server combines current and history rows to rebuild the table at that moment. FOR SYSTEM_TIME ALL returns every version.

FIn which time zone are a temporal table's period columns stored?concept

UTC. SQL Server fills them itself, so a local time must be converted to UTC before using it in AS OF.

MHow do you turn an existing table into a temporal table?coding

Add two DATETIME2 columns GENERATED ALWAYS AS ROW START and ROW END with defaults and a PERIOD FOR SYSTEM_TIME, then SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = ...)). HIDDEN keeps the new columns out of SELECT *.

MCan you edit or delete rows in a temporal history table?concept

Not while versioning is on: updates fail with error 13561 and deletes are blocked too. Only someone with ALTER TABLE permission can turn versioning off, which makes the history trustworthy.

MDoes a temporal table record who changed a row?concept

No, only when. Keep an UpdatedBy column in the row; because it is versioned with the rest of the row, the history then shows who made each change.

SA parent disputes last term's fee. How would temporal tables help, and how would you answer them?scenario

Query the fee table FOR SYSTEM_TIME AS OF the payment time, converted to UTC, and show the amount that was valid then, plus who changed it and when from the versions list. The history cannot be edited, so the answer is reliable.

How to answer:

Walk through the query, the UTC conversion, and how you present the evidence. Mention that without versioning you would depend on invoices and emails.

SCompare audit triggers, temporal tables, and change data capture.concept

Audit triggers keep exactly what you choose and need code. Temporal tables keep every version automatically and answer "as of" questions. Change data capture reads changes from the log for other systems and needs SQL Server Agent.

How to answer:

Compare setup, storage, query style, and requirements, then pick per need: temporal for prices and settings, triggers for custom audit rules, CDC for data feeds.

AWhich tables in a multi-school SaaS would you make temporal, and how would you manage history growth?design

Version tables whose past values matter and change rarely: fees, prices, rates, and settings. Avoid busy tables like attendance. Set a retention period that matches the legal rule, watch history size, and include history tables in backup and archiving plans.

How to answer:

Tie each choice to a business question ("what was it on that date?"), then cover cost, retention, compliance, and operations.

C#

.NET platform

FWhat is the difference between the .NET SDK and the .NET runtime?concept

The runtime only runs .NET applications that are already built. The SDK (Software Development Kit) contains the runtime plus the compiler and the dotnet command-line tools to create, build, test, and publish applications. Developers install the SDK; servers that only run the app need just the runtime.

MWhat is the difference between LTS and STS releases of .NET, and which would you choose for a production system?concept

LTS (Long Term Support) releases, such as .NET 10, get fixes and security patches for 3 years. STS (Standard Term Support) releases get them for 2 years. For a production system that must run for years, like a school system, choose LTS and plan upgrades from one LTS to the next.

FWhat is the CLR?concept

The Common Language Runtime is the part of .NET that runs your compiled code. It loads the IL, turns it into machine code with the JIT compiler, manages memory with the garbage collector, and handles exceptions.

FWhat is IL, and where is it stored?concept

IL (Intermediate Language) is what the C# compiler produces: a platform-neutral set of instructions stored in the .dll file. The CLR turns it into machine code when the program runs.

FWhat is the difference between .NET and .NET Framework?concept

.NET Framework is the original, Windows-only platform; version 4.8.1 is the last, and it only gets maintenance. .NET (Core, then .NET 5 and later) is cross-platform, faster, and where all new development happens.

MWhat does JIT compilation mean, and why does .NET use it?concept

Just-In-Time compilation turns IL into machine code the first time each method runs, on the machine that runs it. The same .dll can therefore run on Windows, Linux, and macOS, and the JIT can optimize for the exact processor.

MWhat are top-level statements?concept

Code written directly in Program.cs without a class or Main method. The compiler generates the Main method for you. Only one file in a project can have them, and they are ideal for small programs and for the startup code of ASP.NET Core apps.

MWhat files does dotnet build produce, and what are they for?concept

In bin/Debug/net10.0: the .dll with your IL, an .exe launcher on Windows, a .pdb with debug information, runtimeconfig.json naming the .NET version to use, and deps.json listing dependencies. They are rebuilt every time and never committed.

SAn app runs on your laptop but fails to start on the server. How do you check whether it is a .NET version problem?scenario

Read the app's runtimeconfig.json to see which framework and version it needs, then run dotnet --list-runtimes on the server. If the matching runtime is missing, install it, or publish the app self-contained so it carries its own runtime.

How to answer:

Show a methodical check: what the app needs, what the server has, and the startup error message. Mention ASP.NET Core apps need the ASP.NET Core runtime, not just the base runtime.

SHow would you organize a .NET solution for a system with an API, shared logic, data access, and tests?design

One solution with projects in src (for example SchoolApp.Api, SchoolApp.Core, SchoolApp.Data) and tests. Core holds models and rules with no dependencies, Data references Core, and the API references both. Tests reference what they test.

How to answer:

Explain the dependency direction and why: Core must not depend on databases or web frameworks, so it stays easy to test and reuse. Mention consistent naming and the .slnx format.

AFramework-dependent or self-contained deployment: how do you choose?design

Framework-dependent apps are small and use the runtime installed on the server, which the operations team patches. Self-contained apps carry their own runtime: larger, but independent of the server, and you must ship updates for security fixes yourself. Containers make this choice simpler, because the image includes the runtime.

How to answer:

Compare size, patching responsibility, and control over the version. Tie the decision to how the organization deploys: managed servers, customer machines, or containers.

Variables and data types

FWhich C# types match the SQL Server types INT, BIGINT, DECIMAL, NVARCHAR, DATE, and BIT?concept

int, long, decimal, string, DateOnly, and bool. Matching the types avoids conversion errors and silently wrong values when data moves between the database and C#.

FWhat does the var keyword do?concept

It lets the compiler work out the variable's type from the value on the right, for example var tuition = 42000.00m; is a decimal. The type is still fixed at compile time; var only saves typing, so use it when the type is obvious.

FWhat is the difference between Parse and TryParse?concept

int.Parse converts text to a number and throws an exception if it cannot. int.TryParse returns true or false and gives the number through an out parameter, so bad input never crashes the program. Use TryParse for anything a person types.

MWhy should money use decimal instead of double?concept

double stores numbers in binary, so most decimal fractions are approximations: 0.1 + 0.2 gives 0.30000000000000004. decimal stores base-10 numbers exactly, so sums of fees and payments are exact. double is for measurements where tiny errors do not matter.

MWhat is the difference between an implicit conversion and an explicit cast?concept

An implicit conversion is always safe and needs no code, such as int to long. An explicit cast may lose data, so you must write it, such as (int)92.75m, which gives 92 because the fraction is cut off, not rounded.

MWhat is the difference between value types and reference types?concept

A value type variable holds the value itself (numbers, bool, char, DateOnly, structs). A reference type variable holds a reference to an object stored elsewhere (string, classes, arrays), and can be null. Copying a value type copies the value; copying a reference copies only the reference.

SSeveral invoices stay 'Partially paid' although families paid in full. What would you check first?scenario

The types used for money. If payments are summed in double, the balance can be a tiny non-zero number such as 0.00000000003, so the status check never sees zero. Change money variables to decimal, then correct the stuck invoices with a one-off script.

How to answer:

Connect the symptom to floating-point rounding, show how you would prove it (print the exact balance), fix the root cause, repair existing data, and prevent it with code review rules.

SWhat happens when an integer overflows in C#, and how do you guard against it?concept

By default it wraps around silently: a byte at 255 plus 1 becomes 0. Choose types large enough for the data, such as long for Ids that can grow, and use a checked block or the project's overflow-checking setting where a wrong value would be dangerous, so overflow throws an exception instead.

How to answer:

Show the default behavior, the risk (wrong totals or Ids), and two defenses: correct type sizing and checked arithmetic. Mention matching SQL types such as TINYINT and BIGINT.

AHow would you keep C# types consistent with the database across a large team?design

Document one type mapping (for example DECIMAL to decimal, DATE to DateOnly), generate or scaffold entity classes from the database where possible, and check mismatches in code review and integration tests that round-trip real data.

How to answer:

Combine a written standard, tooling (scaffolding, analyzers), and tests. Mention that the database stays the source of truth for column types, as the SMS reference file does.

Conditions and loops

FWhat is the difference between = and == in C#?concept

= assigns a value to a variable; == compares two values and returns true or false. Writing if (mark = 33) does not compile in C#: error CS0029, because an int is not a bool.

FWhat are the four loops in C#, and when do you use each?concept

for repeats a known number of times with a counter; while repeats while a condition is true and may run zero times; foreach visits each item in a collection; do...while runs at least once and then checks its condition.

FWhat is the difference between break and continue?concept

break leaves the loop immediately. continue skips the rest of the current round and starts the next one. In a switch statement, break ends each case.

MWhat is the difference between a switch statement and a switch expression?concept

A switch statement runs a block of code per case, with case, break, and default. A switch expression produces a value from arms like >= 91 => "A1", checked from top to bottom, with _ for anything else. Switch expressions are shorter for mapping one value to another.

MWhat happens if a switch expression has no arm that matches the value?concept

The compiler warns with CS8509 that the switch is not exhaustive, and at run time an unmatched value throws SwitchExpressionException. Always end with a _ discard arm.

MWhat does the ternary operator do, and when should you avoid it?concept

condition ? a : b returns a when the condition is true, otherwise b, as a one-line if. Avoid it when the condition or values are complex, or when nested ternaries make the code hard to read; use if or a switch expression instead.

SStudents with exactly 33 marks are shown as failed. How do you find and prevent this kind of bug?scenario

It is a boundary error: the condition uses > where the rule says "33 or more", so it should be >=. Fix the operator, use a named constant such as PassMark, and add tests at the exact boundaries (32, 33, 34) for every rule.

How to answer:

Explain the off-by-one cause, the fix, and the prevention: boundary-value tests and rules kept in one place. Mention re-checking data already produced with the wrong rule.

SA console tool that reads input in a loop hangs forever when run by a scheduled job. Why, and how do you fix it?scenario

When input comes from a file or a job, it can end; Console.ReadLine then returns null every time, so a validation loop never gets valid input. Check for null and break, and design batch tools to read arguments or files instead of prompting.

How to answer:

Show you think about every way a loop can end, including end of input. Mention timeouts and clear exit codes for tools run by schedulers.

AThe grading scale exists in SQL (fn_GetGrade) and in C#. How would you keep business rules consistent?design

Keep each rule in one authoritative place where possible, for example in a shared C# library used by every application, or in the database when reports depend on it. If a rule must exist twice, document it, test both against the same boundary cases, and change them together.

How to answer:

Discuss the trade-off between one source of truth and practical needs such as SQL reports, then the safety nets: shared test cases, code review checklists, and configuration-driven rules.

Arrays and strings

FWhat is an array, and where do its positions start?concept

A fixed-size collection of items of one type, stored under one name. Positions (indexes) start at 0, so the last item is at Length - 1, also written ^1.

FWhat happens when you read an array position that does not exist?concept

The program throws IndexOutOfRangeException: Index was outside the bounds of the array. For a six-item array, valid positions are 0 to 5.

FWhat does string interpolation do?concept

$"..." inserts values into text inside braces, such as $"Topper: {name}". Format specifiers control the output: {average:F2} for two decimals, {serial:D5} for zero padding, {name,-8} for column width.

MWhat does it mean that strings are immutable?concept

A string can never change after it is created. Methods such as Trim and ToUpper return a new string, so name.Trim(); without assigning the result does nothing. Immutability makes strings safe to share between threads and use as dictionary keys.

MWhen should you use StringBuilder instead of +?concept

When building text in a loop. Each += copies all the text so far into a new string, so the cost grows with every line; StringBuilder appends to one buffer. In the SMS, 10,000 CSV lines took about 620 ms with += and 2 ms with StringBuilder.

MHow do you compare two strings while ignoring upper and lower case?coding

string.Equals(a, b, StringComparison.OrdinalIgnoreCase), or methods like Contains and StartsWith with a StringComparison argument. Avoid a.ToUpper() == b.ToUpper(), which creates extra strings and can behave differently across cultures.

SAn export of all students sometimes times out for the largest school. What would you look for?scenario

How the file text is built. Building it with += in a loop has a cost that grows with the square of the size, so small schools are fine and big ones time out. Switch to StringBuilder or write lines straight to a stream, then measure with production-sized data.

How to answer:

Explain why the problem grows faster than the data, how you would prove it with a timer or profiler, and the fix. Mention streaming large files instead of holding them in memory.

SWhat are the risks of parallel arrays, and what is the better design?design

Two arrays kept in step, such as names and marks, break when one is sorted, filtered, or resized without the other, so values attach to the wrong student. Keep related values together in one object, such as a Student class or record, in one collection.

How to answer:

Show the failure concretely (sorting marks only), then the object-based design. Mention that this is the step from procedural code to object-oriented code.

AWhat should a team standardize about string handling in a multi-school, multi-language system?design

Ordinal, case-insensitive comparison for codes, user names, and emails; culture-aware formatting only for text shown to people; a fixed format such as yyyy-MM-dd for files and APIs; Unicode everywhere (NVARCHAR, UTF-8); and StringBuilder or streaming for large output.

How to answer:

Separate machine-facing text (codes, files, APIs: invariant and ordinal) from human-facing text (names, dates on screen: culture-aware). Give one bug each rule prevents.

Methods and parameters

FWhat is the difference between a parameter and an argument?concept

A parameter is the named input in the method's definition, such as decimal maxMarks. An argument is the actual value passed in a call, such as 50m.

FWhat is an optional parameter?concept

A parameter with a default value, such as decimal maxMarks = 100m. Callers can leave it out, and the default is used. Optional parameters must come after the required ones.

FWhat is method overloading?concept

Several methods with the same name but different parameter lists, such as CalculateAttendancePercentage(int, int) and CalculateAttendancePercentage(string). The compiler picks one from the argument types. A different return type alone is not enough.

MWhat is the difference between ref and out?concept

Both pass the caller's own variable. With ref, the variable must be assigned before the call, and the method may read and change it. With out, it need not be assigned before, and the method must assign it before returning. Both keywords appear in the definition and the call.

MWhat is the Try pattern?concept

A method named TryX that returns true or false for success and hands back the result through an out parameter, like int.TryParse. It handles expected failures, such as bad input, without exceptions.

MWhat does the params keyword do?concept

It lets callers pass any number of arguments, which C# collects into an array (or another collection type), such as Average(92m, 85m, 67m). It must be the last parameter.

SA method takes nine parameters. What do you suggest in review?scenario

Too many parameters usually mean the method does too much or the values belong together. Split it into smaller methods, or group related values into an object, such as a request class with properties. Named arguments help readability in the meantime.

How to answer:

Name the smell, explain the risks (wrong order of arguments, hard to test), and offer refactorings: parameter objects, smaller methods, sensible defaults.

SThe same calculation exists in four screens and they disagree after a rule change. How do you fix and prevent it?scenario

Move the calculation into one well-named method with tests at its boundaries, and make every screen call it. Remove the copies. In reviews, treat duplicated business logic as a defect.

How to answer:

Cover the immediate fix (one method, tests), the data fix (correct anything produced wrongly), and prevention (shared library, review rule).

AWhen should an operation return a bool with out parameters, and when should it throw an exception?design

Use the Try pattern when failure is expected in normal use, such as parsing what a user typed. Throw an exception when failure means something is truly wrong, such as a missing database record that must exist. Many APIs offer both, like int.Parse and int.TryParse.

How to answer:

Tie the choice to how often failure happens and who handles it. Mention the cost of exceptions and the clarity of result types in larger systems.

Nullable types

FWhat is a nullable value type?concept

A value type with ?, such as int? or decimal?, that can hold either a value or null. It has HasValue and Value. It maps to SQL columns that allow NULL, such as a mark for an absent student.

FWhat do the ?? and ?. operators do?concept

?? returns the left value unless it is null, then the right value, like SQL's COALESCE. ?. accesses a member only if the object is not null, and returns null otherwise, instead of throwing NullReferenceException.

FWhat causes a NullReferenceException?concept

Using a member, such as .Length or a method, on a variable that holds null. The message is "Object reference not set to an instance of an object." Check for null first, or use ?. and ??.

MWhat are nullable reference types?concept

A compiler feature, turned on with <Nullable>enable</Nullable>, where string means "never null" and string? means "may be null". The compiler warns (CS8600, CS8602, and others) when code might use a null unsafely. It changes warnings, not run-time behavior.

MWhat does the null-forgiving operator ! do, and why is it risky?concept

x! tells the compiler to treat x as not null and silences the warning. It does nothing at run time, so if x is null the program still crashes. Use it only when you truly know better than the compiler, with a comment.

MHow should NULL marks be handled when calculating a class average?coding

Skip them: add only marks that are not null and divide by how many were counted, as SQL's AVG does. Treating an absent student's null as 0 lowers the average unfairly: 395 ÷ 5 is 79, but 395 ÷ 6 is 65.83.

SThe parent app crashes for about one family in five. The log shows NullReferenceException. How do you find and fix it?scenario

Read the stack trace for the exact line, then find which value is null and why, for example a guardian with no email. Fix it where the value is used, with a null check and a sensible fallback, and make the type string? so the compiler warns at every other use.

How to answer:

Show the route from symptom to cause (stack trace, data pattern), the fix, and the prevention: nullable reference types on, warnings as errors, tests with missing data.

SHow do you introduce nullable reference types into a large existing codebase?design

Enable it project by project or file by file (#nullable enable), starting with shared core code. Fix warnings in small batches, annotate public APIs first, and turn warnings into errors once a project is clean, so it stays clean.

How to answer:

Emphasize a gradual, measurable rollout rather than enabling everything at once, and explain why public method signatures are the most valuable place to start.

AHow should 'no value' flow consistently from the database through the API to the client?design

Decide per field: NULL-able columns map to ? types in C#, and the API either returns null in JSON or omits the field, documented in the API contract. Never turn missing data into fake values such as 0 or empty strings, which clients cannot tell apart from real data.

How to answer:

Walk through each layer (database, data access, domain, API, client) and the rule at each. Mention consistency, documentation, and tests with missing data.

Exceptions and debugging

FWhat do try, catch, and finally do?concept

try holds code that might fail. catch runs when a matching exception is thrown in try. finally always runs afterwards, success or failure, so it is used for cleanup.

FWhat happens when an exception is not caught anywhere?concept

It travels up through every calling method. If none catches it, the program stops and prints "Unhandled exception" with the exception type, message, and stack trace.

FWhat is a breakpoint, and what do F10 and F11 do?concept

A breakpoint (F9) pauses the program at a line so you can inspect variables. F10 steps over the current line; F11 steps into the method called on that line. The Locals and Call Stack windows show the values and the chain of calls.

MWhat is the difference between throw; and throw ex;?concept

throw; rethrows the current exception and keeps its original stack trace. throw ex; restarts the stack trace from the rethrow, so the place where the error really happened is lost. The analyzer warns with CA2200. Always use throw;.

MWhy does the order of catch blocks matter?concept

C# uses the first catch block whose type matches. If catch (Exception) comes first, it matches everything, and later specific blocks never run. Put the most specific types first.

MWhen should you throw an exception, and when should you return a result such as false?concept

Return a result for expected situations, such as invalid user input, using the Try pattern. Throw when a rule is broken in a way the method cannot handle, such as a mark above the maximum reaching the save method. Exceptions are for exceptional cases, not normal flow.

SPayments sometimes go missing with no error anywhere. What would you suspect, and how would you investigate?scenario

A swallowed exception: an empty catch or one that logs nothing. Search for empty catch blocks around the save path, use the debugger's Exception Settings to stop where exceptions are thrown, and check database logs. Remove the empty catch so the real error appears, then fix the cause.

How to answer:

Show a structured investigation: reproduce, break on thrown exceptions, read logs, then fix the root cause. Add prevention: review rules against empty catch blocks, and logging with context.

SHow do you read a stack trace to find a bug?concept

Read the exception type and message first, then the at lines from the top, skipping framework methods (System.) until you reach your own code. The first line in your code with a file and line number is usually where to start; the lines below show who called it.

How to answer:

Walk through a real trace. Mention that release builds still give method names, that missing .pdb files remove line numbers, and that throw ex; destroys the useful part.

ADesign an exception-handling strategy for a layered application with an API.design

Validate input early and return clear validation results. Let lower layers throw specific exceptions for broken rules, and do not catch what you cannot handle. Handle everything once, at the edge: global middleware logs the full exception with a correlation id and returns a safe, consistent error response, without exposing internal details.

How to answer:

Cover where exceptions are thrown, where they are caught (one place), what is logged, and what the client sees. Mention custom exception types for domain rules and mapping them to HTTP status codes.

OOP

Classes and objects

FWhat is the difference between a class and an object?concept

A class is a design that describes what something has (properties) and can do (methods). An object is one instance created from it with new. Student is a class; Aarav and Diya are objects with their own values.

FWhat is a constructor?concept

A special method with the class's name and no return type that runs once when an object is created. It sets up the object, and by requiring parameters it ensures no object exists without the values it needs, such as a student's name.

FWhat are the four pillars of object-oriented programming?concept

Encapsulation (a class protects its data and rules), inheritance (a class reuses and extends another), polymorphism (one call behaves differently for different types), and abstraction (code depends on what something does, not how).

MTwo variables refer to one object, and you change a property through one of them. What does the other see?concept

The change. Classes are reference types: assignment copies the reference, not the object, so both variables point to the same object. To get an independent copy, create a new object.

MWhy does == return false for two Student objects with identical values?concept

For classes, == compares references by default: it asks whether both variables point to the same object. Two separately created objects are different objects. Records, or overriding Equals, give value-based equality.

MHow do you create a custom exception, and why would you?coding

Create a class that inherits from Exception and passes the message to base(message), adding any extra data, such as an ErrorNumber. Callers can then catch your application's rule failures separately from system errors and react to them specifically.

SA report shows one student's name with another student's marks. The code uses two arrays. How would you fix it?scenario

The parallel arrays went out of step, probably after sorting one of them. Replace them with one class that holds the student and the mark together, such as ExamResult, and keep a single collection of those objects.

How to answer:

Explain the root cause, the object-based design, and why it removes the whole class of bug. Mention testing the report after sorting and filtering.

SWhat is a 'god class', and how do you avoid one?design

A class that knows and does too much, such as a SchoolManager with hundreds of methods for students, fees, and exams. It is hard to change and test. Split it by responsibility into smaller classes, each with its own data and the rules that use that data.

How to answer:

Give the warning signs (huge files, unrelated methods, many reasons to change), the refactoring approach, and connect it to the Single Responsibility Principle (Lesson 46).

AHow would you decide which classes go into a shared core library?design

Put the domain model and business rules that every application needs (entities, rule exceptions, interfaces) in the core library, with no dependency on UI, databases, or web frameworks. Keep presentation and infrastructure code in the projects that need them, which reference the core, never the other way round.

How to answer:

Explain dependency direction and why it matters for reuse and testing. Mention keeping the core free of Console, HTTP, and SQL so it works from an API, tests, or background jobs.

Encapsulation

FWhat is encapsulation?concept

Keeping an object's data private and offering only safe, public ways to change it, so the object enforces its own rules. A fee invoice's status can change only through RecordPayment.

FWhat do the access modifiers public, private, protected, and internal mean?concept

public: any code. private: only the same class (the default for members). protected: the class and classes that inherit from it. internal: any code in the same project (assembly).

FWhat is the difference between a field and a property?concept

A field is a variable inside a class. A property looks like a field from outside but runs code when read or written, so it can validate, calculate, or restrict access. Public data should be exposed through properties, not public fields.

MWhat is the difference between { get; }, { get; private set; }, and { get; init; }?concept

{ get; } can be set only in the constructor. { get; private set; } can be changed by the class's own methods at any time. { get; init; } can be set in the constructor or an object initializer, and is fixed afterwards.

MWhat is a class invariant? Give an example.concept

A rule that must always be true for an object. For a fee invoice: the status always matches the payments. The constructor checks the starting state and every method keeps the rule, so no sequence of calls can break it.

MWhat does 'tell, don't ask' mean?concept

Instead of asking an object for its data and applying rules outside it, tell the object what to do and let it apply its own rules, such as invoice.RecordPayment(amount). This keeps each rule in one place.

SInvoices show 'Paid' without any payments. How would you find the cause and stop it happening again?scenario

Find every code path that writes the status, such as an admin screen or a direct SQL update. Make the status private set, changed only by the payment method, and restrict direct updates in the database. Correct existing invoices through proper adjustments that leave an audit trail.

How to answer:

Cover investigation (who writes the field), the design fix (encapsulation), the database side (permissions or procedures), and data repair. Mention audit logs to find when it happened.

SShould every property be private or read-only? When is a public setter fine?design

No. Decide per property who legitimately changes it. Ids are set by data access code, simple descriptive fields may be freely editable, but values tied to rules, such as status or balance, should change only through methods.

How to answer:

Show judgment rather than a blanket rule. Give examples of each case and mention that DTOs, used only to carry data, often have public setters by design.

ABusiness rules exist both in SQL constraints and procedures and in C# classes. Is that duplication a problem?design

It is deliberate defense in depth: C# gives fast, clear feedback, and the database protects the data if any path skips the application. Keep the rules consistent with shared error numbers and tests, and decide which layer is authoritative for each rule.

How to answer:

Weigh duplication against safety. Explain which rules belong in the database (integrity) and which in code (workflow), and how to keep both in step.

Inheritance

FWhat is inheritance?concept

A class (the derived class) building on another (the base class), getting all its members and adding its own. Student : Person gets the names and FullName from Person and adds an admission number. Use it for true "is a" relationships.

FWhat does the base keyword do in a constructor?concept

: base(...) calls the base class's constructor with the given arguments, before the derived constructor's own code runs. It is required when the base class has no parameterless constructor.

FDoes C# support multiple inheritance?concept

Not for classes: a class has exactly one base class (error CS1721 otherwise). A class can implement many interfaces, which covers most needs for multiple "kinds" of behavior.

MWhat is the difference between private and protected?concept

private members are visible only inside the class itself, even derived classes cannot use them. protected members are visible to the class and every class that inherits from it, but not to outside code.

MWhat is the difference between is, as, and a cast when converting a base type to a derived type?coding

is with a pattern (if (p is Student s)) checks and converts safely. as returns null when the conversion fails. A cast (Student)p throws InvalidCastException when the object is not a Student. Prefer the is pattern.

MWhy can catch (SchoolRuleException) catch an InvalidMarkException?concept

Because InvalidMarkException inherits from SchoolRuleException, so it is one. A catch block matches the exception's type or any base type, which lets callers handle a whole family of errors at once or a specific one separately.

SA hierarchy Person > Staff > Teacher > ClassTeacher breaks when a teacher stops being a class teacher. What went wrong?scenario

A role that changes over time was modeled as a subclass, but an object cannot change its type. Replace the deep tree with one Teacher class plus data that records the role per year, such as a ClassTeachers table, and keep hierarchies shallow.

How to answer:

Identify the misuse (role as type), the fix (composition or data), and the general rule: if something can change, it is data or a role, not a subclass.

SComposition or inheritance: how do you choose?design

Inherit for true, permanent "is a" relationships, such as a guardian being a person. Use composition, holding another object, for "has a", such as an invoice having payments. Composition is more flexible, so prefer it when in doubt.

How to answer:

Give the tests ("is a" vs "has a", permanence), examples of each, and the costs of wrong inheritance: tight coupling and fragile base classes.

AThe C# model has a Person base class, but the database has separate Students, Teachers, and Guardians tables. Is that a problem?design

No. The class design shares code; the table design suits storage and queries. They may differ as long as the mapping is clear: each derived class maps to its own table, including the inherited columns. ORMs support several mapping strategies for hierarchies.

How to answer:

Explain the object-relational mismatch, the table-per-concrete-type approach used here, and the alternatives (one shared table, or a table per type) with their trade-offs.

Polymorphism

FWhat is polymorphism?concept

One call behaving differently depending on the object's real type. Calling Describe() on a Person variable runs the student, teacher, or guardian version, depending on which object it holds.

FWhat do virtual and override do?concept

virtual in the base class allows derived classes to replace a method or property. override in the derived class provides the replacement. base.Method() inside an override runs the base version too.

FWhy would you override ToString?concept

By default it returns the class name, such as SchoolApp.Core.Entities.Student. Overriding it gives a readable description, which interpolation, logging, and the debugger then use. Never put private data such as passwords in it.

MWhat is the difference between method overloading and method overriding?concept

Overloading: same name, different parameters, usually in one class, chosen at compile time. Overriding: same signature, new body in a derived class, needs virtual and override, chosen at run time from the object's real type.

MWhat is the difference between override and new on a method?concept

override replaces the base method for every caller. new hides it: callers using a base-type variable still get the base version, and only derived-type variables see the new one. Hiding is almost always a mistake; the compiler warns with CS0114 when neither keyword is used.

MWhat is the Template Method pattern?concept

A non-virtual method defines a fixed process and calls virtual (or abstract) steps that derived classes fill in. FeeNotice.Send always formats the same way, while Channel and Compose differ per channel.

SA 300-line switch on payment mode must change for every new mode. How would you refactor it?scenario

Create a base class or interface for payment modes with the varying behavior as virtual or abstract members, and one class per mode. Choose the class in one place, then call it through the base type. A new mode becomes one new class, with no edits to existing logic.

How to answer:

Describe the steps (extract behavior, one class per case, single creation point), the benefit (open for extension, closed for modification), and safety (tests per mode before removing the switch).

SWhen is creating a subclass the wrong way to handle a difference?design

When only a value differs, such as a rate or a limit: use a property set in the constructor instead. Use subclasses for different behavior, and interfaces when behavior must be swapped or combined at run time.

How to answer:

Show judgment with examples, and mention the cost of unnecessary classes: more code, deeper hierarchies, and harder changes.

AHow does polymorphism help a large system grow without breaking existing features?design

New behavior is added as new classes behind an existing base type or interface, so tested code is not edited. Only the place that chooses the implementation changes. This keeps changes small, reviewable, and low-risk, and lets teams work on different implementations independently.

How to answer:

Connect it to the Open/Closed Principle, plug-in architectures, and dependency injection in ASP.NET Core, with an SMS example such as notification channels.

Abstract classes and interfaces

FWhat is an abstract class?concept

A class marked abstract that cannot be created with new, only inherited from. It can hold shared code and abstract members without a body, which every derived class must override, such as ReportCard.FormatScore.

FWhat is an interface?concept

A contract listing members a class promises to provide, such as INotificationSender with Channel, CanReach, and Send. It has no constructors or instance fields; a class implements it with : IName and must provide every member.

FCan a class implement more than one interface?concept

Yes, any number, while having only one base class. A Teacher inherits from Person and is also an ISoftDeletable; a class could implement several capability interfaces at once.

MWhat is the difference between an abstract class and an interface, and when do you use each?concept

An abstract class can hold fields, constructors, and shared code, and a class can have only one; it models "is a" for related classes. An interface is a contract a class can implement alongside others; it models "can do". Use an abstract class for shared code, an interface for a capability with possibly unrelated implementations.

MWhat are default interface methods?concept

Since C# 8, an interface member can have a body that implementing classes inherit, such as Describe() in INotificationSender. They are reachable only through the interface type, and they let you add members to an interface without breaking existing implementations.

MWhat is abstraction in OOP?concept

Depending on what something does, not how it does it, and hiding the details. Notify knows only that a sender can reach a guardian and send a message; email servers and phone gateways stay hidden in the implementations.

SThe SMS calls a text-message provider directly from forty places, and the school wants to switch providers. What would you do?scenario

Introduce an interface such as INotificationSender, wrap the current provider in one class that implements it, and change the forty call sites to use the interface. Then the new provider is one new class plus one line of setup, and both can be tested with fakes.

How to answer:

Describe the refactoring steps safely (introduce the interface, migrate callers gradually, keep behavior identical), then the payoff: vendor independence and testability.

SShould every class have an interface?design

No. Add an interface when you need to swap implementations, fake a dependency in tests, or define a contract between teams or layers. An interface with one implementation and no such need only adds files and indirection.

How to answer:

Show judgment: name concrete reasons to add an interface and the cost of adding them everywhere. Mention that dependency injection in ASP.NET Core makes interfaces cheap where they are useful.

AHow do interfaces and abstract classes differ when a public contract must evolve over years?design

Adding an abstract member to either breaks every implementation. Adding a normal or virtual method to an abstract class, or a default method to an interface, does not. Design contracts small and stable, version them deliberately, and prefer adding new interfaces over changing widely used ones.

How to answer:

Discuss compatibility for libraries and APIs, the role of default interface methods, and strategies such as new interfaces, adapters, and versioning.

static, sealed, partial

FWhat is the difference between a static member and an instance member?concept

A static member belongs to the class and has one shared copy, called on the class name, such as SchoolRules.GetGrade(92m). An instance member belongs to each object and is called on an object, such as diya.GetAgeOn(date).

FWhat is a static class?concept

A class that holds only static members and can never be instantiated (error CS0712). It suits pure helpers and rules with no stored state, such as SchoolRules or Math.

FWhat does sealed mean on a class?concept

No other class may inherit from it; trying fails with error CS0509. Seal concrete classes that were not designed for extension, such as Student and Teacher.

MWhat is the difference between const and static readonly?concept

const is fixed at compile time and allowed only for simple types such as numbers and strings; other projects copy the value when they compile. static readonly is set once at run time and works for any type, such as DateOnly, and callers always read the current value.

MWhat are partial classes used for?concept

Splitting one class across several files that the compiler joins. The main use is generated code: a tool such as EF Core scaffolding writes one file, and your own code in another file survives regeneration.

MWhen should you avoid making a class static?concept

When it has dependencies or behavior you may want to replace, such as sending messages or reading the database. Static code cannot be swapped through an interface or faked in tests. Keep static for pure, deterministic rules.

STwo clerks received the same admission number on the first day of admissions. The number came from a static field. Explain and fix.scenario

A static field is shared by every request in the app and resets when the app restarts; with several copies of the API, each has its own counter. Concurrent requests and restarts produce duplicates. Move the counter to the database, such as a SQL SEQUENCE, protected by a unique constraint.

How to answer:

Explain the three failure modes (concurrency, restarts, multiple instances), the fix, and the safety net of a unique constraint. Mention reviewing every non-readonly static field.

SShould classes be sealed by default?design

Many teams seal concrete classes by default and unseal deliberately. Sealing documents that a class was not designed for inheritance, prevents fragile overrides, and allows small performance gains. Leave classes open only when extension is part of the design.

How to answer:

Present both views: the safety of sealing versus flexibility for library users. Mention that removing sealed later is safe, while adding it later breaks existing subclasses.

AWhere should shared, changing state live in a system that runs several copies of a web API?design

Never in static fields or memory of one instance. Durable shared state belongs in the database (sequences, rows with constraints) or a shared store such as a distributed cache; per-request state lives in objects created for that request. Static members hold only constants and pure logic.

How to answer:

Discuss scale-out, restarts, and concurrency, then the right home for each kind of state. Mention that this is why ASP.NET Core services are registered with scoped or transient lifetimes.

Enums, structs, records

FWhat is an enum, and why use one?concept

A type with a fixed list of named values, such as InvoiceStatus { Unpaid, PartiallyPaid, Paid, Cancelled }. It replaces magic strings: invalid values and typos fail the build, and editors list the valid options.

FWhat is a record in C#?concept

A type, written in one line such as record MarkEntry(int EnrollmentId, int ExamSubjectId, decimal? MarksObtained), with init-only properties, value equality, a readable ToString(), and with expressions for copies with changes.

FHow do you convert an enum to and from a string?coding

status.ToString() returns the member name, such as "PartiallyPaid". Enum.Parse<InvoiceStatus>("Paid") converts text back, and Enum.TryParse does it safely, returning false for unknown text.

MWhat is the difference between a struct and a class?concept

A struct is a value type: assignment copies the whole value, it cannot be null (unless nullable), and it cannot inherit. A class is a reference type: assignment copies a reference to one shared object. Use structs for small immutable values, classes for entities.

MWhat is the default value of an enum, and why can it be a problem?concept

0, whether or not a member has that value. If no member is 0, an unset enum field holds an undefined value, as with Gender. Make 0 a safe default, or require the value in the constructor, and use Enum.IsDefined for values from outside.

MWhat does a with expression do?coding

It creates a copy of a record (or struct) with some properties changed, leaving the original untouched: entered with { MarksObtained = 90m }. It is how you "change" immutable data.

SA report shows zero 'partial' invoices because C# used the string 'Partial' and the database stores 'PartiallyPaid'. How do you prevent this class of bug?scenario

Replace status strings with an enum whose member names match the database CHECK constraint exactly, and convert with ToString() and Enum.Parse. Typos then fail the build, and a test can check that every enum name is allowed by the constraint.

How to answer:

Explain the root cause (unchecked strings), the fix (enums matching the schema), and an automated guard (a test comparing enum names with the CHECK constraint values).

SShould entities like Student be records?design

Usually not. Entities have identity: two students with identical names and birth dates are still different people, distinguished by Id, and they change over time. Records compare by value and are meant to stay fixed, which suits DTOs, messages, and value objects.

How to answer:

Contrast identity equality with value equality, and mutability with immutability. Mention that ORMs track entities by key, which value equality can confuse.

AHow would you choose between class, struct, record, and record struct across a codebase?design

Classes for entities with identity and behavior; records for data passed between layers and compared by value; readonly record structs for tiny, frequently created values; enums for fixed option lists. Document the convention so the whole team chooses the same way.

How to answer:

Give the decision criteria (identity, mutability, size, equality semantics) and the costs of wrong choices, such as large struct copies or entities compared by value.

Model classes

FWhat is an entity (model) class?concept

A class that represents one row of a database table, with one property per column, such as Mark for the Marks table. Data access code reads rows into entities and saves entities back as rows.

FWhat does the required keyword do on a property?concept

Introduced in C# 11, it forces the property to be set in the object initializer when the object is created; otherwise the build fails with CS9035. It suits entities without constructors, such as Subject.Name.

FHow do you represent a column that allows NULL in an entity class?concept

Add ? to the type: decimal? for MarksObtained, string? for Remarks, DateOnly? for a return date. NOT NULL columns use the plain type, so the class tells callers exactly what may be missing.

MWhat is the difference between a foreign key property and a navigation property?concept

The foreign key property, such as StudentId, holds the stored Id and is always present. The navigation property, such as Student, holds the linked object and is filled only if the code loaded it, so it is nullable.

MHow do you avoid repeating audit columns in many entity classes?design

Put them in an abstract base class, such as AuditableEntity with CreatedAt, CreatedBy, UpdatedAt, and UpdatedBy, and a SoftDeletableEntity for soft-delete columns. Entities inherit what their table has.

MHow are junction tables such as StudentGuardians modeled in C#?concept

As a class with the two foreign keys, which together form the key, plus any data about the link, such as Relationship and IsPrimaryContact, and optional navigation properties to both sides. There is no separate Id.

SDiscounts of 2.50 are saved as 2. The column is DECIMAL(10,2). What do you check, and how do you prevent it?scenario

The entity property type: it is probably int, which drops the fraction. Change it to decimal, fix affected data, and add an automated test that compares every entity's property types and nullability with the database columns, so a mismatch fails the build.

How to answer:

Trace the value through the layers to find where the fraction is lost, then fix code, data, and process. Mention schema-comparison tests or scaffolding as long-term protection.

SRich entities or plain (anemic) entities: which do you prefer?design

A mix. Put rules inside entities where breaking them is expensive, such as payments and identity, so invalid objects cannot exist. Keep simple lookup tables plain, with rules in services. Fully anemic models scatter rules; fully rich models can fight data access tools.

How to answer:

Define both styles, give their trade-offs, and show judgment per entity. Mention that EF Core supports private setters and constructors, which makes rich entities practical.

AHand-written entities or entities generated from the database: what would you choose for a large system?design

For a database-first system with many tables, generate (scaffold) them so they always match the schema, and keep custom code in partial classes. Hand-write them when the domain model must differ from the tables. Either way, verify them automatically against the schema.

How to answer:

Compare effort, accuracy, and flexibility. Mention partial classes for custom code, regeneration on schema changes, and code-first migrations as the alternative where C# owns the schema.

DTOs and mapping

FWhat is a DTO?concept

A data transfer object: a simple class or record that carries exactly the data one API call or screen needs, such as StudentDto. It has no business rules and no database-only fields.

FWhy should an API not return entity classes directly?concept

Entities mirror the database and expose everything: password hashes, audit columns, soft-delete flags, and any column added later. DTOs send only what the client needs, so internal data cannot leak and database changes do not break clients.

FWhat is an extension method?concept

A static method in a static class whose first parameter has this, such as ToDto(this Student student). It can be called like an instance method, student.ToDto(), without changing the original class. Its namespace must be imported with using.

MWhy use separate DTOs for responses, create requests, and update requests?design

Each direction needs different fields: a response has an Id and readable values; a create request has no Id; an update request contains only fields that may change. One shared DTO would accept or expose fields it should not.

MWhat is over-posting (mass assignment), and how do DTOs prevent it?concept

A client adds extra fields to a request, such as a status or role, and the server saves them because it bound the request to an entity. Request DTOs contain only the allowed fields, so anything else in the JSON is ignored.

MWhat is flattening in mapping?concept

Building one simple DTO from values spread across linked entities, such as an invoice summary that includes the student's name from Enrollment.Student. Clients get a small, ready-to-show shape without knowing how tables are joined.

SA security review finds the profile endpoint returns the password hash. How do you fix it and prevent it across the codebase?scenario

Introduce a DTO with only the needed fields and map the entity to it before returning. Check all other endpoints for returned entities, add a review rule or analyzer that forbids entities in controller responses, and consider rotating credentials if hashes were exposed.

How to answer:

Cover the immediate fix, the audit of similar endpoints, prevention (rules, tests that inspect response shapes), and the incident response, such as assessing exposure.

SHand-written mapping or a mapping library such as AutoMapper?design

Hand-written mapping is explicit, compiler-checked, and easy to debug; renamed properties break the build. Libraries reduce repetitive code for many similar mappings but can silently skip properties. Choose per project size, and test mappings either way.

How to answer:

Weigh explicitness and safety against less code. Mention configuration validation in libraries and source-generated mappers as a middle ground.

AHow do DTOs help an API evolve without breaking mobile apps?design

The DTO is the public contract; the database and entities can change behind it while mapping adapts. Breaking changes to the DTO are made deliberately, with versioning, so apps already on phones keep working.

How to answer:

Explain contract stability, additive versus breaking changes, and API versioning strategies, with an example such as renaming a database column without changing the JSON.

Advanced C#

Collections

FWhat is the difference between an array and a List<T>?concept

An array has a fixed size set when it is created. A List<T> grows and shrinks with Add and Remove, using an array inside that it replaces with a bigger one when full. Use arrays for fixed data and lists for data that changes.

FWhen would you use a Dictionary<TKey, TValue>?concept

When you look values up by a unique key, such as students by admission number. Lookup time stays about the same however many items it holds, unlike searching a list.

FWhat is the difference between a Queue and a Stack?concept

A Queue<T> is first in, first out: Enqueue adds at the back, Dequeue takes from the front, like a fee counter line. A Stack<T> is last in, first out: Push and Pop work on the top, like undo.

MWhy is looking up by key in a Dictionary faster than searching a List?concept

A list search checks items one by one, so on average half the list per search. A dictionary hashes the key to jump almost directly to its bucket, taking about constant time. In the SMS, finding 1,006 students took about 24 ms with a list and 0.1 ms with a dictionary.

MWhat is the difference between dict[key] and dict.TryGetValue(key, out value)?coding

The indexer throws KeyNotFoundException when the key is missing. TryGetValue returns false instead and gives the value through out when found. Use TryGetValue whenever the key may be absent.

MWhat does 'Collection was modified; enumeration operation may not execute' mean?concept

The list was changed, for example by Remove, while a foreach was looping over it. Collect the items to change and apply the changes after the loop, or loop backwards with a for loop.

SAn end-of-term report takes minutes. It loops over students and, for each, searches a list of all marks. How do you fix it?scenario

The nested search does students times marks comparisons. Group the marks into a Dictionary keyed by student once, then look each student up in constant time. The work drops from millions of comparisons to one pass plus one lookup per student.

How to answer:

Identify the nested loop as the cause, explain the complexity in plain terms, and show the dictionary fix with a measurement before and after.

SHow should a class expose a collection it owns?design

Keep the real list private and expose it as IReadOnlyList<T> or IReadOnlyCollection<T>, so callers can read but not add or remove. Changes go through the class's own methods, which keep its rules. Initialise collections to empty, never null.

How to answer:

Connect it to encapsulation, show the property pattern, and mention that returning the mutable list lets callers bypass validation.

AHow do you choose the right collection for a feature?design

Start from how the data is used: in order and by position (List), by key (Dictionary), uniqueness checks (HashSet), arrival order (Queue), last-first (Stack), and whether many threads share it (concurrent collections). Measure with realistic data volumes before optimizing further.

How to answer:

Give a decision approach based on access patterns and scale, with SMS examples, and mention thread safety and memory as further factors.

Generics

FWhat are generics in C#?concept

Classes, records, interfaces, and methods written with a type parameter, such as T, that the caller fills in. List<Student> and PagedResult<StudentDto> reuse one definition for many types, with full compile-time type checking.

FWhat is a generic method?concept

A method with its own type parameter, written after its name, such as ToPage<T>(List<T> all, int page, int pageSize). The compiler usually infers T from the arguments, so callers rarely write it.

FWhy are generic collections better than ArrayList?concept

ArrayList holds object, so wrong types are accepted and fail later with InvalidCastException, and value types are boxed. List<decimal> rejects a string at compile time and stores decimals directly, which is safer and faster.

MWhat are generic constraints? Give examples.concept

Rules on what a type parameter may be, written with where: where T : ISoftDeletable, where T : class, where T : struct, where T : new(). They let the generic code use the promised members, and the compiler rejects types that do not qualify (CS0311).

MWhat is boxing, and how do generics avoid it?concept

Boxing wraps a value type, such as a decimal, in an object on the heap so it can be stored as object; unboxing casts it back. It costs memory and time. Generic collections store the value type directly, so no boxing happens.

MWhy can't a List<Student> be assigned to a List<Person>, while IEnumerable<Person> works?concept

Through a List<Person>, code could add a Teacher into a list of students, so C# forbids it (CS0029). IEnumerable<T> only reads, so treating students as persons is safe; this is covariance, marked by out T on the interface.

SFour teams each built their own paging response for the API, and the mobile app struggles. What do you do?scenario

Define one generic PagedResult<T> in the shared library with agreed names, 1-based pages, and a maximum page size, and migrate endpoints to it gradually, keeping old shapes until clients move. Clients then need one paging routine.

How to answer:

Cover the shared contract, the rules it enforces (page size limits), and a safe migration plan with versioning or a transition period for existing clients.

SWhat are the pros and cons of a generic repository, IRepository<T>?design

Pros: less repetitive code and a uniform interface. Cons: every entity gets the same methods, including Delete where rules forbid it; special queries are awkward; and it often duplicates what an ORM already provides. Specific repositories, possibly sharing a small generic base, are a common choice.

How to answer:

Present both sides fairly, tie the decision to business rules (forbidden deletes) and query needs, and mention that EF Core's DbSet already acts as a generic repository.

AHow would you design shared generic building blocks for a large API without over-generalizing?design

Generalize proven, repeated shapes, such as paging, result wrappers, and soft-delete filters, with minimal constraints, in a shared library. Keep domain logic specific. Make something generic only when a second real use appears, and document the conventions so teams use them consistently.

How to answer:

Show judgment: name good candidates and bad ones (generic services hiding business rules), discuss constraints and naming, and the cost of changing widely used generic types.

IEnumerable and IQueryable

FWhat is IEnumerable<T>?concept

The interface for anything you can walk through one item at a time. It provides an enumerator, which foreach uses. Arrays, lists, dictionaries, and LINQ queries all implement it.

FWhat does yield return do?concept

It hands back one item from a method that returns IEnumerable<T>, then pauses the method until the caller asks for the next item. Data is streamed: reading the marks file with Take(3) read only 71 of 12,012 lines.

FWhat is deferred execution in LINQ?concept

Building a query with methods like Where does not run it; it creates a plan. The plan runs only when results are requested, by foreach, Count(), First(), ToList(), and similar calls.

MWhat is the difference between IEnumerable<T> and IQueryable<T>?concept

An IEnumerable query holds compiled code and runs in your application's memory. An IQueryable query holds an expression tree that a provider translates, for example EF Core into SQL, so filtering happens in the database before rows are sent.

MWhat is multiple enumeration, and how do you avoid it?concept

Enumerating the same deferred query more than once repeats all its work each time; two Count() calls read the marks file twice. If the results are needed several times, call ToList() once and reuse the list.

MWhy prefer Any() over Count() > 0?coding

Any() stops at the first matching item; Count() must examine every item. Against a database, Any() becomes an EXISTS check while Count() counts every matching row.

SA dashboard calls context.AttendanceRecords.ToList() and then filters today's records in C#. It is slow and uses a lot of memory. Why, and what is the fix?scenario

ToList() runs the query immediately, so every attendance row is loaded into memory before filtering. Apply Where while the query is still IQueryable, then ToList(), so SQL Server returns only today's rows.

How to answer:

Explain where the query runs before and after the fix, quantify the waste (all rows versus a few hundred), and mention checking the generated SQL or logs to confirm.

SShould a repository return IQueryable<T>?design

Usually not. Returning IQueryable lets callers compose any query against the database, spreading data access logic and making performance unpredictable. Return materialized results such as IReadOnlyList<T>, and add specific methods for the queries you need.

How to answer:

Present the trade-off: flexibility versus control and testability. Mention cases where exposing IQueryable is deliberate, such as OData or internal query builders.

AHow would you process millions of rows in .NET without running out of memory?design

Stream instead of materializing: read rows one at a time with an iterator, a data reader, or IAsyncEnumerable<T>, process each, and keep only aggregates. Filter and aggregate in the database where possible, and batch writes.

How to answer:

Combine database-side work, streaming in the application, batching, and measuring memory. Mention that ToList on huge results is the usual cause of memory spikes.

LINQ

FWhat is LINQ?concept

Language Integrated Query: a set of C# methods and syntax for querying any collection, such as Where, Select, OrderBy, and GroupBy. The same queries work on lists, files, and, through EF Core, databases.

FWhat is the difference between Where and Select?concept

Where filters: it keeps items that match a condition. Select projects: it turns each item into a new shape, such as a name and a mark. Filter first, then shape.

FWhat is the difference between First, FirstOrDefault, and Single?concept

First returns the first match and throws if there is none. FirstOrDefault returns default (null for classes) instead of throwing. Single expects exactly one match and throws for none or for more than one.

MHow does LINQ's Average treat null values?concept

For nullable values, Average, Max, and Min skip nulls, like SQL's AVG. The Class 10 Mathematics average of 60.23 ignored 20 absent students, matching SQL Server exactly.

MHow does GroupBy work in LINQ?coding

GroupBy(m => m.Subject) returns groups; each has a Key (the subject) and is itself the sequence of items with that key, so g.Average(...) and g.Count() work per group, like SQL's GROUP BY.

MWhat is the difference between Select and SelectMany?concept

Select returns one result per item, so a list of sections with enrollments becomes a list of lists. SelectMany flattens those inner lists into one sequence: 22 sections become 1,006 enrollments.

SA results screen shows a different rank-1 student on every refresh. What is wrong?scenario

Several students share the top mark and the sort has no tie-breaker, so their order is not fixed. Add ThenBy on a stable key, and agree a ranking rule with the school, such as equal marks sharing a rank (DENSE_RANK).

How to answer:

Explain non-deterministic ordering, the technical fix, and the business question behind it. Mention the same issue in SQL ORDER BY without a unique key.

SQuery syntax or method syntax: which do you use?concept

Both compile to the same calls. Method syntax is shorter for simple chains and offers every operator; query syntax reads more easily for joins and multiple sources. Many teams default to method syntax and use query syntax for complex joins.

How to answer:

Show you can read and write both, then state a consistent team preference and its reason.

AWhen does LINQ hurt performance, and how do you prevent it in a team?design

Through searches inside loops instead of dictionaries, repeated enumeration of deferred queries, materializing database queries too early, and sorting before filtering. Prevent it with code review rules, analyzers for multiple enumeration, logging of generated SQL, and measuring hot paths.

How to answer:

Give concrete anti-patterns with fixes, then the team-level practices. Emphasize measuring before replacing readable LINQ with hand-written loops.

Delegates and events

FWhat is a delegate?concept

A type-safe reference to a method, stored in a variable and passed around like a value. Func, Action, and EventHandler<T> are built-in delegate types; LINQ's Where takes a delegate.

FWhat is the difference between Func and Action?concept

Func returns a value; its last type parameter is the return type, as in Func<decimal, string>. Action returns nothing, as in Action<string>.

FWhat is a lambda expression?concept

An inline, unnamed method, such as m => m.MarksObtained is null. It is converted into a delegate (or an expression tree for IQueryable), with parameter types inferred from where it is used.

MWhat is an event, and how does it differ from a public delegate field?concept

An event is a delegate wrapped so that outside code can only subscribe (+=) and unsubscribe (-=); only the owning class can raise it. A public delegate field could be overwritten or invoked by anyone, faking notifications (CS0079 prevents this for events).

MWhat is a closure?concept

A lambda that captures variables from its surrounding scope. It captures the variable itself, not a copy, so changes are shared and the captured objects stay alive as long as the lambda does.

MWhy raise an event with Event?.Invoke(...), and why can't you unsubscribe an inline lambda?coding

With no subscribers the event is null, so ?. avoids a NullReferenceException. Each inline lambda creates a new delegate, so -= with another identical-looking lambda removes nothing; keep a reference or use a named method.

SRecording a payment calls six features directly, and a bug in any one breaks payments. How would you redesign it?scenario

Have the payment raise one "payment recorded" event, or publish a message, after the payment is saved, and let each feature subscribe independently. Failures in optional reactions should not undo or block the payment; isolate them and log errors.

How to answer:

Connect to Single Responsibility and Open/Closed, discuss error isolation, and mention that across services this becomes messaging with background processing.

SWhen would you use an event, an interface, or a Func parameter?design

An event for optional listeners that come and go; an interface for a required collaborator with several methods, injected through the constructor; a Func parameter for a single rule or formula chosen by the caller.

How to answer:

Give one SMS example for each and the trade-offs: discoverability, testability, and how failures propagate.

AHow do in-process events relate to messaging in a distributed system?design

Both announce that something happened and let others react. In-process events run synchronously in the same program and are lost if it crashes. Messaging (queues, an outbox) is durable, crosses services, retries on failure, and runs asynchronously, at the cost of eventual consistency.

How to answer:

Compare reliability, coupling, and timing, then explain when to promote an event to a message, for example a payment notification that must not be lost.

Modern C# features

FWhat is a collection expression?concept

C# 12 syntax for creating collections with square brackets: string[] subjects = ["English", "Science"];. It works for arrays, lists, and other collection types, and .. spreads another collection's items in.

FWhat is a raw string literal, and when is it useful?concept

Text between three double quotes ("""), where quotes and backslashes need no escaping and the closing quotes' indentation is removed. It suits SQL, JSON, and other text with quotes; values still belong in SQL parameters.

FWhat does the C# 14 field keyword do?concept

Inside a property accessor, field refers to the property's compiler-made backing field, so a property with a custom setter, such as trimming or validation, no longer needs a hand-written private field.

MWhat are list patterns?concept

Patterns that match the shape of a sequence: ["Absent", ..] (first item is Absent), [.., "Absent", "Absent"] (last two), [_, _, _] (exactly three items). _ matches one item and .. any number of items.

MHow do primary constructors on classes differ from records?concept

Both declare parameters after the type name. A record turns them into public init-only properties with value equality. A class with a primary constructor only makes the parameters available inside the class body; they are not properties, and they are not read-only.

MWhat are C# 14 extension members?concept

An extension(Type receiver) { ... } block inside a static class that can declare extension properties as well as methods, such as student.Initials. Before C# 14, only extension methods were possible.

SA developer converted half the codebase to new C# syntax in one pull request. How do you handle it?scenario

Ask to split it: a large mechanical change hides real changes and is hard to review. Agree on which features the team adopts, apply them in new and changed code, and convert old code gradually or with automated, separately reviewed refactorings.

How to answer:

Balance modernization against reviewability and risk. Mention coding standards, analyzers or editorconfig rules, and keeping behavior changes separate from style changes.

SShould a switch over an enum end with a default arm? What are the trade-offs?design

Without _, the compiler warns about missing statuses (CS8509) and unnamed values (CS8524), which helps when new statuses are added. A quiet default hides new statuses. A common choice is to list every status and end with _ => throw, so unexpected values fail loudly.

How to answer:

Explain both warnings, the risk of silent defaults, and the throwing default as a middle path.

AHow would you keep a large codebase current with new .NET and C# versions?design

Upgrade to each LTS release on a plan, update the target framework and packages, fix analyzer warnings, and adopt new language features through agreed coding standards in new and changed code. Automated tests make upgrades safe, and editorconfig or analyzers keep the style consistent.

How to answer:

Cover the upgrade cadence (LTS), risk control (tests, staged rollout), and team practices for adopting features. Mention support end dates as the business driver.

async and await

FWhat do async and await do?concept

async marks a method that can use await and returns Task or Task<T>. await pauses the method until a task completes, giving the thread back in the meantime, and continues from the same line afterwards.

FWhat is the difference between Task and Task<T>?concept

Both represent work that finishes later. Task has no result, like writing a log file; Task<T> produces a value of type T, like Task<string> for a send status.

FDoes async make code run faster?concept

Not by itself. It makes waiting for I/O cheaper by freeing threads, which improves scalability and lets independent waits overlap. CPU-bound calculations need parallelism instead.

MHow do you run several independent async operations together?coding

Start them without awaiting, collect the tasks, and await Task.WhenAll(tasks). Ten 250 ms sends took about 260 ms together instead of 2.6 seconds one by one. Results come back in the same order.

MWhat is a CancellationToken, and why pass it through async methods?concept

A token that signals that work should stop, created by a CancellationTokenSource, for example with a time limit. Passing it down to every async call lets the whole operation stop early; ASP.NET Core cancels it when the client disconnects.

MWhy should you avoid async void?concept

An async void method cannot be awaited, so callers cannot know when it ends, and exceptions it throws cannot be caught by the caller and can crash the process. Return Task instead; use async void only for event handlers.

SA web portal stops responding under load, but the CPU is nearly idle. The code uses .Result on database calls. What is happening?scenario

Thread pool starvation: each request blocks a thread while waiting for the database, so the pool runs out and new requests queue. Make the call chain async all the way with await, so threads are released during waits.

How to answer:

Explain the symptom (low CPU, high latency), the cause (blocked threads), the fix, and how to confirm it with thread pool counters or dotnet-counters.

SHow are exceptions handled with Task.WhenAll?concept

WhenAll waits for all tasks to finish, then await rethrows the first exception; the other tasks still complete. Inspect each task's status or the aggregate Exception to see all failures, and design batches so one failure does not stop the rest.

How to answer:

Show awareness that only the first exception surfaces through await, and how to collect all errors for reporting in batch jobs.

AHow would you send fee reminders to 10,000 families reliably and quickly?design

Send asynchronously with limited concurrency (for example batches or a semaphore) so the provider is not overwhelmed, with timeouts and cancellation, retries for temporary failures, and a record of what was sent so a restart does not send twice. Run it as a background job, not inside a web request.

How to answer:

Cover throughput (bounded concurrency), reliability (retries, idempotency, persistence), provider limits, and observability. Mention background workers in Module 12.

Threading

FWhat is the difference between a thread and a task?concept

A thread is a path of execution managed by the operating system. A task is a unit of work that .NET schedules, usually on a reusable thread-pool thread. Modern code uses tasks, Parallel, and async instead of creating threads by hand.

FWhat is a race condition?concept

A bug where the result depends on the timing of threads that share data. Two threads doing count++ can both read the same value and write the same result, losing an update; one million increments gave about 62,000.

FWhat does Parallel.ForEach do?concept

It processes the items of a collection on several thread-pool threads at once, using multiple cores. It suits CPU-bound, independent work, such as building 1,006 report cards about three times faster on 16 cores.

MWhen would you use Interlocked instead of lock?concept

Interlocked performs a single update on one number, such as increment or add for int and long, as one uninterruptible step, without blocking. Use lock when several fields change together, for types like decimal, or for collections.

MWhy might parallel code be much less than N times faster on N cores?concept

Splitting and combining work costs time, cores share memory bandwidth, locks make threads wait, and parts of the program run on one thread only (Amdahl's law). Very small work items can even be slower in parallel.

MIs Dictionary thread-safe? What do you use instead?concept

No: adding from several threads at once can lose items or corrupt it. Use ConcurrentDictionary (or other System.Collections.Concurrent types), or let each thread build its own results and combine them afterwards.

SA parallel term-end report gives a slightly different fee total each run. What is wrong, and how do you fix it?scenario

Threads add to one shared total without protection, so updates are lost in a race. Fix it by computing independent partial totals per section or thread and adding them at the end, or by protecting the shared total with a lock. Then test repeatedly with production-sized data.

How to answer:

Recognise the symptom of nondeterminism, name the race, give the share-nothing fix first and the lock as an alternative, and mention why such bugs pass normal tests.

SWhat is a deadlock with locks, and how do you avoid one?concept

Two threads each hold one lock and wait for the lock the other holds, so both wait forever. Avoid it by taking locks in a fixed order, keeping locked sections small, avoiding nested locks, and never awaiting or calling unknown code while holding a lock.

How to answer:

Explain the circular wait, prevention rules, and diagnosis with a debugger or dump showing thread stacks. Relate it to the SQL deadlocks of Lesson 25.

AHow do you design a web application so that concurrent requests do not corrupt shared state?design

Keep request handling stateless: per-request objects, no mutable static fields, data in the database with transactions and constraints. Where in-memory sharing is needed, such as caches, use thread-safe types and immutable data, and keep heavy CPU work in background jobs.

How to answer:

Cover the request model (many threads), where state should live, synchronization choices, and service lifetimes in dependency injection (singleton services must be thread-safe).

Memory and GC

FWhat is the difference between the stack and the heap?concept

The stack holds method-local value-type variables and references, freed automatically when a method returns. The heap holds objects such as class instances, arrays, and strings, freed by the garbage collector when nothing references them.

FWhat does the garbage collector do?concept

It periodically finds objects that running code can no longer reach and reclaims their memory, then compacts the surviving objects. Developers do not free managed memory by hand.

FWhat is IDisposable, and what does using do?concept

IDisposable has one method, Dispose, which releases resources the GC does not manage, such as files and connections. using calls Dispose automatically at the end of a block, even if an exception is thrown.

MWhat are GC generations?concept

Generation 0 holds new objects and is collected often; survivors move to generation 1, then to generation 2, which is collected rarely. Most objects die young, so this makes collection cheap. Objects of 85,000 bytes or more start on the large object heap, counted as generation 2.

MWhat is the difference between Dispose and a finalizer?concept

Dispose releases resources at a known moment, called by your code or using. A finalizer runs when the GC collects the object, at an unknown time, on a special thread, and delays collection. Prefer Dispose; modern code rarely writes finalizers because SafeHandle covers them.

MHow can events cause memory leaks?concept

An event holds delegates, and each delegate references its subscriber. If a long-lived object's event keeps a short-lived subscriber, the subscriber cannot be collected until it unsubscribes. Unsubscribe with -=, often in the subscriber's Dispose.

SAn API's memory grows every day until it needs a restart. How do you investigate?scenario

Watch memory and GC counters over time, take memory snapshots at two points, and compare which object types grow and what keeps them alive. Typical culprits are event subscriptions on long-lived services, static collections, unbounded caches, and undisposed resources.

How to answer:

Describe a measured approach (dotnet-counters, dumps or Visual Studio snapshots, retention paths), the common causes, and verifying the fix under load.

SShould you call GC.Collect() in application code?concept

Almost never. The GC tunes its own timing, and forcing collections usually costs performance by promoting objects and pausing the program. It is useful in experiments and tests that measure memory, as in this lesson.

How to answer:

Explain the cost, the rare legitimate cases, and what to do instead: fix the cause of memory growth.

AHow do you design a high-traffic .NET service to be memory-efficient?design

Stream large data instead of loading it, avoid many short-lived large objects, reuse buffers (pooling), bound every cache, dispose resources promptly, avoid long-lived references to per-request objects, and monitor GC metrics in production.

How to answer:

Cover allocation patterns, lifetimes, pooling, caching limits, and observability, with an example such as exporting attendance for a whole school.

Data Access

ADO.NET

FWhat is ADO.NET, and what are its main classes for SQL Server?concept

ADO.NET is the low-level part of .NET for talking to databases. For SQL Server, the main classes come from Microsoft.Data.SqlClient: SqlConnection (the connection), SqlCommand (SQL text or a procedure name), SqlParameter (a value), SqlDataReader (rows, forward only), SqlTransaction, and SqlException. Dapper and EF Core are built on top of it.

FWhat is the difference between ExecuteScalar, ExecuteReader, and ExecuteNonQuery?concept

ExecuteScalar returns one value, the first column of the first row, such as a COUNT(*). ExecuteReader returns a reader over many rows. ExecuteNonQuery runs INSERT, UPDATE, or DELETE and returns the number of rows changed. Each has an Async version that should be preferred.

FWhat is SQL injection, and how do you prevent it in C#?concept

SQL injection is user input changing what a query does, because the input was joined into the SQL text. Typing x' OR '1'='1 into an unsafe student search returned all 10,012 students. Prevent it with parameters: the value travels separately from the SQL, so it is only ever a value.

MWhat is connection pooling, and how should code use connections because of it?concept

ADO.NET keeps a pool of open connections per connection string. Disposing a connection returns it to the pool, and the next open takes it back almost instantly: 100 opens took 3 ms after a first open of 472 ms. So open as late as possible, dispose as early as possible, and never keep a connection in a field.

MHow do you read a nullable column with a SqlDataReader?coding

A NULL column arrives as DBNull.Value, not null, and calling GetString or GetInt32 on it throws. Check reader.IsDBNull(ordinal) first, then read the value, for example Address = reader.IsDBNull(i) ? null : reader.GetString(i).

MHow do you call a stored procedure with an output parameter from ADO.NET?coding

Set CommandType = CommandType.StoredProcedure and use the procedure name as the command text. Add input parameters normally, and add the output parameter with Direction = ParameterDirection.Output and a size. After ExecuteNonQueryAsync, read its Value, as with @ReceiptNumber from usp_RecordFeePayment.

SWhy can AddWithValue slow a query down, and what do you use instead?concept

AddWithValue guesses the SQL type from the C# value, and a string becomes NVARCHAR. Against a VARCHAR column, SQL Server converts the column and can scan instead of seek: finding a student by admission number read 37 pages instead of 2. Use Parameters.Add with an explicit SqlDbType and size that match the column.

How to answer:

Explain the type guess, the implicit conversion on the column side, and its effect on index use. Give the fix, and mention that plan-cache bloat from varying string lengths is a second reason.

SA school portal becomes slow at 9 a.m., then fails with 'Timeout expired... obtaining a connection from the pool'. What do you check?scenario

The pool is exhausted: connections are being opened and not returned. Look for connections, readers, or commands that are not disposed, especially on exception paths, and for connections held during slow work. Fix with await using everywhere, short-lived connections, and async calls; only then consider raising Max Pool Size.

How to answer:

Name the cause (pool exhaustion), how to confirm it (counters or sp_who for sleeping connections from the app), the code fixes, and why raising the pool size first only hides the leak.

AWhen would you still choose plain ADO.NET over Dapper or EF Core in a new system?design

When you need full control or maximum throughput with no mapping layer: bulk loading with SqlBulkCopy, streaming huge result sets, table-valued parameters, or a small hot path measured as too slow. For ordinary CRUD, the hand-written mapping costs more in time and bugs than it saves, so most teams use EF Core or Dapper and drop to ADO.NET only where measured.

How to answer:

Show you know the trade-off: control and speed against code volume and mistakes. Give concrete cases, and say how you would keep such code isolated behind a repository.

Dapper

FWhat is Dapper, and how is it different from EF Core?concept

Dapper is a micro-ORM: you write the SQL, and it adds parameters and maps result rows to objects. EF Core is a full ORM: it also writes the SQL from LINQ, tracks changes to entities, and saves them. Dapper gives more control with less magic; EF Core gives more productivity for everyday CRUD.

FWhich Dapper methods would you use to get a list, a single row, and a count?coding

QueryAsync<T> for a list, QuerySingleOrDefaultAsync<T> for one row by a unique key (null if none, an exception if two), and ExecuteScalarAsync<int> for a count. ExecuteAsync runs INSERT, UPDATE, DELETE, or a procedure and returns the rows changed.

FHow do you pass parameters to a Dapper query, and is it safe from SQL injection?concept

Pass an object, often anonymous: new { LastName = lastName } fills @LastName. Dapper creates real parameters, so the values never become part of the SQL text and injection is not possible. Joining user input into the SQL string yourself is still unsafe.

MHow does Dapper match columns to properties, and what happens when a name does not match?concept

By name, ignoring case. A column with no matching property is ignored, and a property with no column keeps its default value; neither raises an error. That makes renamed columns or missing aliases a silent bug, so use explicit column lists with aliases and test each query.

MWhat is multi-mapping in Dapper, and what does splitOn do?coding

Multi-mapping reads one joined row into several objects, for example an Enrollment and its Student, and a function you supply connects them. splitOn names the column where each next object starts; it defaults to Id. For one-to-many results, a dictionary keeps one parent per key.

MHow do you read an output parameter from a stored procedure with Dapper?coding

Use DynamicParameters: add the inputs, and add the output with a type, a size, and direction: ParameterDirection.Output. Call ExecuteAsync with commandType: CommandType.StoredProcedure, then read it with Get<string>("@ReceiptNumber").

SYour Dapper search by admission number is slow, although the column has a unique index. What could be wrong?scenario

Dapper sends C# strings as NVARCHAR(4000). Against the VARCHAR column, SQL Server converts the column and may scan the index instead of seeking. Pass new DbString { Value = ..., IsAnsi = true, Length = 15 } so the parameter matches the column type, then confirm the seek in the plan.

How to answer:

Start from the symptom, explain the implicit conversion, show the DbString fix, and say how you would prove it: the execution plan or logical reads before and after.

SA dashboard makes six small queries per page load. How would you reduce the cost with Dapper?scenario

Send them together with QueryMultipleAsync and read each result in order from the grid reader: one round trip instead of six. Select only the columns the dashboard shows, mapped to DTOs or tuples. If it is still slow, look at the queries' plans and consider caching (Module 12).

How to answer:

Name round trips as the cost, show QueryMultiple, mention the order-dependent reading, and add what you would measure before and after.

AWould you use EF Core and Dapper in the same application? How would you organize it?design

Yes, commonly: EF Core for writes and ordinary reads of entities, where change tracking and LINQ save time, and Dapper for heavy reports and dashboards, where hand-tuned SQL matters. Both use the same connection string and can share a transaction. Keep each behind a repository or query interface so callers do not know which tool answers.

How to answer:

Give the split by workload, mention sharing connections and transactions, and explain how the abstraction keeps the choice reversible. A brief CQRS mention fits at this level.

EF Core basics

FWhat is EF Core, and what is a DbContext?concept

EF Core is Microsoft's ORM for .NET: you query with LINQ, and it writes the SQL, creates objects, tracks changes, and saves them. A DbContext is one session with the database; each DbSet<T> is a table you can query. A context should be short-lived, such as one per web request.

FWhat is the difference between database-first and code-first?concept

Database-first starts from an existing database: schema changes are made in SQL, and EF Core maps to the result, often helped by scaffolding. Code-first starts from C# classes, and EF Core migrations create and change the database. Database-first fits shared or older databases; code-first fits new apps that own their database.

FWhat does SaveChangesAsync do?concept

It looks at every tracked entity, finds the added, modified, and deleted ones, and sends the matching INSERT, UPDATE, and DELETE statements in one transaction. Changing one property of a loaded student produced an UPDATE of that single column.

MWhat does dotnet ef dbcontext scaffold generate, and why use --no-onconfiguring?concept

It reads a database and writes one class per table and view, plus a DbContext with the full mapping: lengths, types, keys, indexes, defaults, and relationships. Without --no-onconfiguring, it also puts the connection string in the generated code, which leaks credentials into source control.

MWhat is a value converter in EF Core? Give an example.coding

It translates a property value to a column value and back. In the SMS, Gender is an enum in C# and a CHAR(1) code in the database: HasConversion(g => ((char)g).ToString(), c => (Gender)c[0]). HasConversion<string>() stores an enum by name. Converters also apply to query parameters.

MWhy might EF Core throw 'The LINQ expression could not be translated', and how do you fix it?concept

The query calls something SQL cannot run, such as your own C# method (s.GetAgeOn(date)). EF Core throws instead of loading everything. Rewrite the condition with translatable parts, such as a date comparison, rather than calling ToList first and filtering in memory.

SHow do you map rich domain entities, with constructors and read-only properties, to an existing database with EF Core?design

Keep the entities in the core project and put all mapping in IEntityTypeConfiguration classes in the data project. EF Core can call a constructor whose parameter names match properties, map read-only properties that are configured explicitly, and use value converters for enums. The entities need no EF Core attributes or base classes.

How to answer:

Describe the layering first, then the specific features (constructor binding, explicit property mapping, backing fields, converters), and say how you verified the mapping, such as comparing against the scaffolded model.

SA colleague wants to scaffold the database again every time a column changes, overwriting the entity classes. What do you advise?scenario

Regenerating overwrites anything added by hand, such as rules, constructors, or enums, and makes the domain model follow the database. Keep scaffolded output as a reference only, map hand-written entities through configuration classes, and change one configuration line when a column changes.

How to answer:

Explain the risk with a concrete loss, propose the separation, and mention a check that catches mapping drift, such as an integration test or a column comparison script.

AWho should own schema changes in a database-first EF Core system, and how do you keep code and database in step?design

The database scripts are the source of truth, reviewed and versioned like code, and run in order by deployment. EF Core mappings follow them. Keep both in one repository, deploy the script before the code that needs it, prefer additive changes, and run integration tests against a database built from the scripts so drift fails the build.

How to answer:

Cover ownership, versioning, deployment order, backward-compatible changes, and automated drift detection. Compare briefly with code-first migrations.

EF Core relationships

FWhat is a navigation property in EF Core?concept

A property that points to a related entity instead of holding a value. A reference navigation points to one entity, such as Enrollment.Section; a collection navigation holds many, such as FeeInvoice.Payments. The foreign key, such as SectionId, is always loaded; navigations only when requested.

FWhat do Include and ThenInclude do?coding

Include loads a navigation of the entity being queried; ThenInclude continues from that navigation to the next level. Kabir's student, enrollments, sections, classes, and years came back in one query with Include(s => s.Enrollments).ThenInclude(e => e.Section).ThenInclude(...).

FWhat is the difference between eager, explicit, and lazy loading?concept

Eager loading fetches related data in the same query with Include. Explicit loading fetches it later, on request, with Entry(...).Collection(...).LoadAsync(). Lazy loading fetches it automatically the first time a navigation is read, through proxies, which hides queries and often causes N+1 problems.

MHow do you configure a one-to-many relationship with the Fluent API?coding

From either side, for example builder.HasMany(i => i.Payments).WithOne(p => p.FeeInvoice) .HasForeignKey(p => p.FeeInvoiceId). Use WithMany() with no argument when the other side has no collection. Configuring it explicitly is needed when names do not follow conventions, such as ClassId with a SchoolClass navigation.

MWhat is a global query filter, and when would you use one?concept

A condition EF Core adds to every query on an entity, configured with HasQueryFilter. It suits rules that must never be forgotten, such as hiding soft-deleted rows or, in multi-tenant systems, other tenants' rows. IgnoreQueryFilters switches it off; EF Core 10 can switch off one named filter.

MWhy might SaveChanges fail on a table with triggers, and how do you fix it?concept

EF Core reads generated values back with an OUTPUT clause, and SQL Server rejects OUTPUT without INTO on tables with enabled triggers. Declare each trigger with ToTable("Marks", t => t.HasTrigger("tr_Marks_Audit")), and EF Core switches to a method that works.

SA fee report shows full balances for invoices that are partly paid. The code calls invoice.Balance. What do you suspect?scenario

The invoices were loaded without their payments, so Payments is empty and AmountPaid is 0. Nothing throws. Add Include(i => i.Payments), or better for a report, project the sum of payments in SQL, and add a test with a partly paid invoice so the bug cannot return quietly.

How to answer:

Explain why missing related data is silent, give both fixes and when each fits, and finish with how you would prevent a regression.

SWould you enable lazy loading in a web API? Why or why not?design

Generally no. Every navigation access can issue a query, so loops become N+1 problems, the queries are invisible in the code, and serializing an entity can trigger loads across the whole graph. Load deliberately with Include or project to DTOs, which also keeps the API's shape independent of the entities.

How to answer:

Give the performance and predictability reasons, mention serialization, and offer the alternative you would use. Acknowledge where lazy loading can be acceptable, such as small desktop tools.

AHow would you design soft delete and multi-tenancy filtering so no query can forget them?design

Put both rules in named global query filters on every affected entity, set the tenant from the request through the DbContext, and allow switching a filter off only in specific admin or repair code paths. Add database-side protection too, such as row-level security or filtered views for tenancy, and tests that fail if an entity lacks the filter.

How to answer:

Cover the EF Core mechanism, the source of the tenant value, the controlled escape hatch, defense in depth in the database, and automated checks. Module 13 builds the multi-tenant version.

EF Core performance

FWhat does AsNoTracking do, and when should you use it?concept

It tells EF Core not to keep snapshots of the loaded entities for change tracking. Use it for read-only queries such as lists, reports, and searches. Loading 10,012 students took about 65-77 ms with it and 376-456 ms without it, with identical SQL.

FWhat is the N+1 problem?concept

Running one query for a list and then one more query for each item: 1 + N round trips. It often hides in a loop or behind lazy loading. Fix it with one query that returns everything, such as an Include or a projection with a subquery: 51 queries became 1 for a section's average marks.

FHow do you page results with EF Core?coding

Order the query, then use Skip((page - 1) * pageSize).Take(pageSize), which becomes OFFSET and FETCH in SQL. Return the total count for page numbers, and end the ordering with a unique column such as Id, so rows never repeat or disappear between pages.

MWhy is a projection to a DTO often better than loading entities?concept

It reads only the columns the DTO needs, creates no entities, and is never tracked. It also keeps internal columns, such as audit fields, away from the screen or API. Use entities when you will change and save them; use projections for everything that only reads.

MWhat are ExecuteUpdateAsync and ExecuteDeleteAsync, and what do they skip?concept

They send one UPDATE or DELETE statement for every row matching a LINQ query, without loading entities. Graduating 1,006 students took 1 command instead of 25. They skip the change tracker, entity rules, and anything your SaveChanges logic does, such as setting audit columns, and tracked objects in memory are not refreshed.

MWhat is a cartesian explosion, and how does AsSplitQuery help?concept

Including several collections in one query repeats each parent row for every combination of child rows, so the result can grow enormously. AsSplitQuery() loads each collection with its own query. The trade-off is extra round trips and possible inconsistency if data changes between the queries.

SA page in the SMS is slow, and the team blames EF Core. How do you investigate?scenario

Measure first: log the SQL and count the queries for one page load. Many similar queries mean N+1; one huge query may mean too many includes or columns; a slow single query needs its execution plan and indexes. Then apply the matching fix and measure again with the same data.

How to answer:

Give a method, not a list of tips: measure, classify the cause, fix, and verify. Mention tools such as the EF Core command log, query counters, and SQL Server execution plans.

SWhen would you use a compiled query, and what does it actually save?concept

For very frequent queries with the same shape, such as a lookup by key on every request. It saves EF Core's work of matching the LINQ expression to its cached SQL, not the database time. On SchoolDb, 1,000 lookups were about 20% faster. For ordinary queries, the extra code is not worth it.

How to answer:

State what is cached anyway, what compiling removes, and give a measured gain to keep it in proportion.

AHow would you set data-access performance rules for a team, so problems are caught before production?design

Agree on defaults: projections for reads, no lazy loading, paging on every list, bulk methods for simple mass changes. Log slow queries and query counts per request in every environment, add tests or alerts that fail when a request exceeds a query budget, and run load tests on realistic data volumes such as 10,000 students before release.

How to answer:

Combine coding standards, automated detection, and production monitoring. Mention a realistic data set and query budgets per endpoint.

Testing

FWhat is the difference between a unit test and an integration test?concept

A unit test checks one class's logic alone, with fakes for its dependencies, and runs in milliseconds. An integration test checks parts working together, such as a repository with the real SQL Server, so it finds wrong SQL, mapping, and constraints that fakes cannot.

FWhat is the difference between [Fact] and [Theory] in xUnit?coding

A [Fact] is a test with no inputs. A [Theory] runs once for each set of inputs supplied by [InlineData] rows or a [MemberData] property; each set is reported as its own test. The fee tests use a theory for zero, negative, and too-large amounts.

FWhat does Arrange, Act, Assert mean?concept

A structure for each test: Arrange sets up the objects and data, Act calls the one behaviour being tested, and Assert checks the result. It keeps tests short, readable, and focused on one behaviour.

MWhat is a fake, and how is it different from a mock?concept

A fake is a simple working implementation, such as a repository that stores students in a list. A mock is usually generated by a library and set up with expected calls and answers. Fakes are easy to read and reuse; mocks are handy for checking interactions. Both depend on the code using interfaces.

MHow do you keep integration tests from leaving data in the database?coding

Run each test inside a transaction that is rolled back. With TransactionScope created with TransactionScopeAsyncFlowOption.Enabled and never completed, every connection opened inside joins the transaction, whatever the tool, and disposal rolls it back. Alternatives are a fresh database per run or deleting test data, both slower or more fragile.

MWhat is a regression test? Give an example.concept

A test written for a bug that already happened, so it cannot come back unnoticed. In SchoolApp, an invoice loaded without its payments showed the full balance; a test now loads Diya's partly paid invoice and checks that the balance is 25,500.

SYou have three repository implementations. How do you make sure they behave the same?design

Write one integration test class against the interface, and run every test once per implementation with a theory and MemberData. Four tests became twelve for ADO.NET, Dapper, and EF Core. Where behaviour legitimately differs, such as exception types, assert on what matters to callers or translate the differences in the data layer.

How to answer:

Describe the shared contract tests, how inputs select the implementation, and what to do about differences the tests uncover.

SYour integration tests pass alone but fail when run together. What do you check?scenario

Shared state: tests that rely on data left by others, missing rollbacks, identity or sequence values assumed to be fixed, or a transaction lost after await because the scope was not created with async flow. Make each test arrange its own data, roll back everything it writes, and never assume run order.

How to answer:

List the likely causes, explain how to confirm each (run in a different order, inspect the data), and give the structural fix rather than ordering the tests.

AHow would you design a test strategy for a system like the SMS, from unit tests to production?design

Many fast unit tests for rules and services with fakes; integration tests for every repository and query against a database built from the real scripts; a few end-to-end API tests for key flows such as admission and fee payment; and data-consistency checks. Run unit tests on every change, integration tests in CI, and keep realistic data volumes for performance tests.

How to answer:

Use the test pyramid, say what each level catches and when it runs, and mention test data, database setup in CI, and how failures block a release.

Transactions and concurrency

FHow does EF Core use transactions when you call SaveChangesAsync?concept

Each SaveChangesAsync call runs all its INSERT, UPDATE, and DELETE statements in one transaction: either all are saved or none. Taking a payment saved the payment and the invoice's new status together. For several saves or mixed raw SQL, use Database.BeginTransactionAsync().

FWhat is the lost update problem?concept

Two users read the same data, both change it based on what they read, and the second save overwrites or contradicts the first. Two clerks each took 6,000 from an invoice with 6,000 due, because both screens showed 6,000; without a check, the invoice ended paid 16,000 of 10,000.

FWhat is a ROWVERSION column in SQL Server?concept

A binary value that SQL Server changes automatically on every update of the row; you never set it. Comparing the version you read with the current one tells you whether someone changed the row in between, which is the basis of optimistic concurrency.

MWhat is the difference between pessimistic and optimistic concurrency?concept

Pessimistic concurrency locks the data while working, so nobody else can change it, as usp_RecordFeePayment does with UPDLOCK. Optimistic concurrency takes no lock and checks at save time that the data has not changed, such as with a rowversion. Optimistic suits screens where users think between reading and saving; pessimistic suits short operations with frequent conflicts.

MHow do you add optimistic concurrency to an entity in EF Core?coding

Map a ROWVERSION column as a concurrency token with IsRowVersion(), either on a byte[] property or as a shadow property, builder.Property<byte[]>("RowVersion").IsRowVersion(). EF Core then adds AND RowVersion = @original to every UPDATE and DELETE, and throws DbUpdateConcurrencyException when no row matches.

MWhat happens to tracked entities when you roll back an EF Core transaction?concept

Nothing: the rollback undoes the database, but the objects keep their changed values, and the change tracker treats them as saved. The cancelled invoice still said Cancelled in memory while the database said Unpaid. Discard the DbContext and reload after a rollback.

SA clerk gets a concurrency error when taking a fee payment. What should the application do?scenario

Not show the raw exception. Translate DbUpdateConcurrencyException into a clear error, such as 50014 "the invoice was changed by someone else", reload the invoice so the clerk sees the current balance, and let them decide again. Never retry a money operation automatically with stale values.

How to answer:

Cover translation, reloading, and user decision, and explain why automatic retry or "client wins" is wrong for payments, while it may be fine for low-risk fields.

SWhen do you need an explicit transaction in EF Core instead of relying on SaveChanges?concept

When one business operation needs several SaveChangesAsync calls, mixes EF Core with raw SQL or another tool, or must read and write under one isolation level. Keep it short, commit at the end, and roll back on any error. If connection retries are enabled, run the transaction inside the execution strategy, because retries cannot replay a user-started transaction.

How to answer:

Give concrete triggers, show the begin, commit, rollback shape, and mention the execution strategy caveat and why long transactions hurt concurrency.

AHow would you choose between ADO.NET, Dapper, and EF Core for a new system like the SMS?design

Default to EF Core for everyday work with rules, because units of work, concurrency tokens, and LINQ remove much code and many bugs. Use Dapper for heavy reports where hand-tuned SQL matters, and ADO.NET for special cases such as bulk copy or streaming. Keep all of them behind repository interfaces, and keep critical rules in the database too.

How to answer:

Decide by workload, not by preference; mention mixing tools in one solution, shared transactions, team skills, and measurement before switching tools.

EF Core migrations

FWhat is an EF Core migration?concept

A C# class, written by dotnet ef migrations add, with an Up method that changes the database to match the model and a Down method that undoes it. EF Core records applied migrations in the __EFMigrationsHistory table, so database update runs only the ones a database does not have yet.

FWhat is the difference between database-first and code-first?concept

Database-first: the database is designed in SQL, and EF Core reads it. Code-first: the C# classes are the design, and migrations create and change the database. Database-first suits shared or older databases; code-first suits a database that one application owns.

FWhich dotnet ef commands do you use day to day with migrations?coding

migrations add <Name> to create one, migrations script to see its SQL, database update to apply all pending ones, database update <Name> to go back or forward to one, migrations remove to delete the last unapplied one, and migrations list to see them.

MWhy must you read a migration before applying it? Give examples.scenario

EF Core guesses from the model difference, and some guesses lose data. A rename combined with another change becomes DropColumn plus AddColumn. A new required foreign key gets default 0 that matches no row. Defaults such as cascade delete may not be what the business wants. Read Up, Down, and the SQL, and fix them.

MHow do you write a data migration, for example moving a text column into a new table?coding

Edit the generated migration: create the new table, copy the data with migrationBuilder.Sql, add and fill the new key column, and only then drop the old column and add the foreign key. Write Down to move the data back. Wrap hand-written SQL in EXEC(N'...') so idempotent scripts still compile, and test both directions.

MHow do you apply migrations to a production database?concept

Not from the app at startup. Generate an idempotent script (migrations script --idempotent) for a reviewer or DBA to run, or build a migration bundle (migrations bundle) that the release pipeline runs with the production connection string. Both skip migrations already in __EFMigrationsHistory.

SShould an application call Database.Migrate() when it starts?design

Usually not in production. EF Core 9 and later take a lock so two instances do not both migrate, but the app's login then needs permission to change the schema, a long migration delays start-up, and a failed migration stops the app from starting. Run migrations once in the release, with a script or bundle, under a separate login.

How to answer:

Mention the lock, then permissions, start-up time, failure handling, and the alternative.

SHow do you keep migrations healthy in a team where several developers change the model?scenario

One kind of change per migration, reviewed in pull requests with its SQL. Never edit or remove a migration others have applied; add a new one. Resolve snapshot merge conflicts carefully and run migrations has-pending-model-changes in the build so a model that disagrees with the migrations fails CI. Test migrations, including Down, against a copy of real data before release.

How to answer:

Cover small migrations, review, never rewriting applied ones, snapshot conflicts, CI checks, and testing.

AHow do you change a large production database without downtime?design

Use expand and contract: first add new structures without breaking the old ones (new nullable columns or tables, both written by the app), backfill data in batches, switch reads to the new structure in a release, and only later remove the old columns. Keep every step backward compatible with the running version, avoid long blocking operations (online index builds, batched updates), and have a tested rollback for each step.

How to answer:

Explain expand and contract, compatibility between versions, batching, locking, and rollback per step.

Architecture

Backend basics

FWhat does a backend developer do?concept

A backend developer builds the parts of an application that users never see: the database, the business rules, and the APIs that apps call. They are responsible for data being correct, safe, and fast. In a School Management System, that means the attendance tables, the rule that marks cannot exceed the maximum, and the API the mobile app uses.

FWhat is the difference between frontend and backend?concept

The frontend is what users see and click: a website or mobile app running on their device. The backend runs on a server: it stores data, applies business rules, and exposes APIs. The frontend never touches the database; it calls the backend over HTTP.

MWhy do teams usually design the database before writing application code?concept

Data outlives applications: screens and services get rewritten, but school records stay for years. The tables decide what the code can do, and changing a table after real data exists means migrating that data. Designing the data model early also exposes missing requirements, such as a student having two guardians, before any code depends on them.

SWhat makes a project production-ready rather than tutorial-level?concept

A production-ready system enforces its rules on the server and in the database, not only on the screen. It handles two users saving at once, records who changed what, restricts data by role, logs errors, has tests, and stays fast with realistic data volumes. A tutorial usually shows only the happy path with ten rows.

How to answer:

Start with the definition (rules, security, reliability, performance, observability). Then give SMS examples: marks above the maximum are refused by the database, receipt numbers are unique even with double clicks, every marks change is audited. Finish with the trade-off: you cannot build everything at once, so say what you would add first (data integrity and security) and what can wait (caching, advanced monitoring).

Modules

MHow would you split a School Management System into modules?design

Split it by business capability: masters (years, classes, sections, subjects), students and guardians, enrollment, attendance, exams and marks, fees, users and roles, and a dashboard. Each module owns its tables and endpoints. Note the dependencies: attendance, marks, and fees all depend on enrollment, so masters and enrollment are built first.

Layers

SWhere should validation happen: in the screen, the API, or the database?scenario

In all three, for different reasons. The screen validates for quick feedback, the API validates every request because any client can call it directly, and the database constraints are the last safety net. For example, "marks cannot exceed 100" is shown on the screen, rejected by the API with 400, and blocked again by the database.

How to answer:

Explain the three purposes (user experience, authority, integrity). Use one SMS rule and show it at each layer. Then cover the trade-off: duplicated rules must stay in sync, so the API is the single source of business rules and the database holds only rules that must never be broken (uniqueness, required values, valid ranges).

SThe class list page takes 8 seconds to load. How do you find which layer is slow?scenario

Measure each layer instead of guessing. The browser's network tab shows how long the API call took; the API logs show how much of that was the database call; the database's execution plan shows why the query is slow. The usual causes are a missing index, a query returning far more rows than the screen needs, or many small queries in a loop.

How to answer:

Describe the top-down method (browser, API, database) with the tool for each layer. Give the SMS case: the list of 40 students in 10-A should not scan 10,000 enrollments. End with the fix and how you would prove it worked: before and after timings.

AWhy should a website or mobile app never connect directly to the database?design

The database credentials would have to live on every user's device, where anyone can extract them. There would be no single place to apply business rules and permissions, and every app would break whenever a table changes. An API keeps the database private, applies the rules once for every client, and gives apps a stable contract.

How to answer:

State the risks (security, duplicated rules, tight coupling to the schema). Use the SMS: a parent's app must only see their own child's marks, which only the server can enforce. Acknowledge the cost: an extra layer adds a little latency and code to maintain, which is worth it for any system with more than one client or sensitive data.

Requirements

FWhat is the difference between functional and non-functional requirements?concept

A functional requirement describes what the system does, such as "a teacher marks daily attendance". A non-functional requirement describes how well it does it: speed, security, reliability, such as "the class list loads in under 2 seconds". Both must be written down and testable.

FWhat is a user story?concept

A user story is a short requirement written from the user's point of view: "As a [role], I want [action], so that [benefit]". For example: "As a class teacher, I want to mark attendance for my whole section in one screen, so that I finish it in five minutes." It is completed with acceptance criteria that define when it is done.

FWhat is a role in requirements, and why do we list roles?concept

A role is a type of user with its own permissions, such as Teacher, Accountant, or Parent. Listing roles shows who uses each feature and what each must not be allowed to do. Roles later become rows in a Roles table and permission checks in the API.

MWhat are acceptance criteria, and how do you write them?concept

Acceptance criteria are the checks that prove a story is done. A common format is Given / When / Then: given a starting situation, when the user acts, then a specific result happens. Each criterion should be testable, for example "given attendance for 10-A is already saved today, when the teacher saves again, then records are updated, not duplicated".

MHow do requirements turn into database tables?design

The important nouns become tables (Student, Section, Exam), and their details become columns. Rules become constraints, such as a unique admission number or marks within the maximum. Relationships become foreign keys or junction tables, for example a student with two guardians. Non-functional requirements shape the design too, such as soft delete and audit columns.

Environments

SThe code works on your machine but fails on the test server. How do you investigate?scenario

Compare everything that can differ: tool and runtime versions, configuration and connection strings, environment variables, database data and schema, and permissions. Read the server's logs for the exact error, then reproduce it locally with the same settings. Most cases come down to a version or configuration difference.

How to answer:

Give a structured checklist (versions, configuration, data, permissions, logs) rather than guesses. Use an SMS example: the test server runs an older SQL Server or a different connection string. Finish with prevention: pinned versions written in the README, the same database scripts for every environment, and configuration kept out of code.

SOLID

FWhat does SOLID stand for?concept

Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion: five principles that keep object-oriented code easy to change as it grows.

FWhat is the Single Responsibility Principle? Give an example.concept

A class should have one reason to change. In the SMS, FeeNotice decides the wording and an INotificationSender decides the delivery channel, so a wording change and a provider change each touch one class.

FWhat is a repository?concept

An object that stores and finds entities so the rest of the code never deals with SQL, such as IStudentRepository with GetByAdmissionNumber and Add. Its interface lives with the business rules; implementations live in the data layer.

MWhat is the Open/Closed Principle?concept

Code should be open for extension and closed for modification: add behavior by writing new classes behind an existing abstraction, not by editing tested code. A new notification channel is a new INotificationSender; the Notify method never changes.

MWhat is the Liskov Substitution Principle? Give an example of breaking it.concept

A derived class must work wherever its base class is expected, keeping the base class's promises. A ReportCard subclass whose FormatScore throws NotSupportedException compiles, but breaks any code holding a ReportCard.

MWhat is the difference between dependency inversion and dependency injection?concept

Dependency inversion is a design principle: high-level rules depend on abstractions they own, not on low-level details. Dependency injection is a technique: dependencies are passed in from outside, such as through a constructor. A DI container automates the injection.

SA service creates its own SQL repository with new inside a method, and now an offline mode is needed. What do you change?scenario

Introduce or use a repository interface, have the service receive it through its constructor, and create the concrete repository in one composition root. The offline version becomes a new class implementing the interface, and the service can be tested with an in-memory fake.

How to answer:

Name the principle (dependency inversion), show the refactoring steps safely, and mention the side benefit: unit tests without a database.

SWhat is a composition root?concept

The single place, usually at application startup, where concrete implementations are chosen and wired together, such as new StudentService(new InMemoryStudentRepository()). The rest of the code depends only on abstractions; in ASP.NET Core, Program.cs with the DI container plays this role.

How to answer:

Explain why one place matters: swapping an implementation is one change, and nothing else knows concrete types. Connect it to service registration in ASP.NET Core.

AWhen does applying SOLID become over-engineering?design

When principles are applied without a real cost to remove: interfaces with one implementation and no tests, factories for simple objects, layers that only pass calls through. Apply a principle when you can name the change or test it makes easier; keep pure, stable code simple, like a static rules class.

How to answer:

Show judgment with examples on both sides, and explain how you decide in reviews: name the expected change, weigh indirection against benefit, refactor when the need appears.

Design patterns

FWhat is a design pattern?concept

A named, proven solution to a recurring design problem, described as a shape of code rather than a library. Names such as Factory or Decorator let developers communicate a whole design in a word.

FWhat is the Factory pattern? Give an example.concept

A method or class whose job is to decide which object to create, so the decision lives in one place. NotificationSenderFactory.For(guardian) returns an email or phone sender; callers never write new EmailSender() themselves.

FWhat is the Strategy pattern?concept

A family of interchangeable rules behind one interface, chosen at run time. IGradeScale has a primary-band strategy and an A1-to-E strategy; the report code uses whichever it is given.

MWhat is the Decorator pattern, and where does .NET use it?concept

A class that implements an interface and wraps another object of the same interface, adding behavior before or after passing calls on, like LoggingSender. ASP.NET Core middleware, stream wrappers, and retry or caching layers follow the same idea.

MWhat is the Observer pattern, and how does C# support it?concept

A subject notifies many observers when something happens, without knowing them. C# events implement it directly: FeeInvoice.PaymentRecorded notifies every subscriber after a payment.

MWhat are the problems with the classic Singleton pattern?concept

Any code can reach it through a static property, so dependencies are hidden; tests cannot replace it; and its shared state must be thread-safe. Registering the class as a singleton service with dependency injection keeps one instance while making it explicit and replaceable.

SA text-message provider needs retries and logging. A colleague proposes copying the provider class and adding both. What do you suggest?scenario

Use decorators: a retrying wrapper and a logging wrapper around the unchanged provider, all implementing the same interface. Each concern stays separate and testable, and any future provider gets both by being wrapped the same way.

How to answer:

Name the pattern, explain why copying duplicates and couples concerns, and mention ordering of decorators (logging outside retrying shows each attempt or not) and DI registration.

SWhen is using a design pattern over-engineering?design

When it removes no real cost: a factory that always returns one class, a strategy interface with one implementation and no plan for more, decorators no one needs. Apply a pattern when you can name the repeated decision, changing rule, or extension it supports.

How to answer:

Give concrete signs of over-engineering and the cost (more files, indirection), then a rule for deciding, such as introducing the pattern when the second variant appears.

AWhich patterns does ASP.NET Core rely on, and how does that shape application design?design

Dependency injection (replacing factories and singletons), decorators in the middleware pipeline, strategies for logging and configuration providers, and options and observers for configuration changes. Applications should depend on interfaces, register implementations in one place, and add cross-cutting concerns as middleware or decorators.

How to answer:

Connect each framework feature to its pattern, then explain the consequences for structuring SMS code: thin controllers, services behind interfaces, cross-cutting concerns outside business logic.

Repository pattern

FWhat is the repository pattern?concept

An interface between business code and data access. The service asks the repository for entities, such as GetByAdmissionNumberAsync, and never sees SQL, connections, or the ORM. Implementations can use ADO.NET, Dapper, EF Core, or memory without the service changing.

FWhat are the layers of a typical .NET application, and which way do the dependencies point?concept

A host layer (console or Web API) that starts the app and wires implementations, a core layer with entities, rules, services, and interfaces, and a data layer with the database code. Host and Data reference Core; Core references neither, so the rules depend on nothing that changes often.

FWhat is a composition root?concept

The single place where concrete implementations are chosen and connected to the interfaces that use them. In SchoolApp's console it is Program.cs; in an ASP.NET Core app it is the dependency injection registration at startup. Everywhere else, code receives interfaces through constructors.

MHow does the repository pattern apply dependency inversion?concept

The high-level core project defines the interface it needs, IStudentRepository, and the low-level data project implements it. The compile-time dependency points from Data to Core, the opposite of the call direction, so the rules never depend on database details.

MWhat is a unit of work, and how does it relate to EF Core's DbContext?concept

A unit of work collects several changes and saves them together in one transaction, or not at all. A DbContext already is one: it tracks changes and SaveChangesAsync writes them atomically. With ADO.NET or Dapper you build it yourself, sharing one connection and transaction across operations.

MWhy should a repository not return IQueryable?concept

Callers would then compose queries, so database concerns, such as what can be translated to SQL and when the query runs, leak into the service layer, and the repository can no longer be swapped or faked faithfully. Return finished results: entities, DTOs, or pages.

SA teammate proposes a generic IRepository<T> with GetAll, GetById, Add, Update, and Delete for every table on top of EF Core. How do you respond?design

It mostly duplicates DbSet<T>, offers methods nobody should call, such as GetAll on 10,000 students, and often leaks IQueryable. Specific repositories with methods named after real needs, or the DbContext directly in simple apps, give the same isolation with clearer intent.

How to answer:

Acknowledge the goal (consistency), list the concrete problems, propose the alternative, and say when you would accept a small generic base class for shared plumbing.

SYour in-memory test repository and the real database behave differently in a test. Give an example and say how you would handle it.scenario

In SchoolApp, a rolled-back transaction removed a new student from SQL Server, but the in-memory repository kept it, because a dictionary does not take part in transactions. Unique constraints, case rules, and generated values can differ too. Keep fast unit tests on fakes for rules, and run integration tests against the real database for behaviour that depends on it.

How to answer:

Name the leaky abstraction, give a concrete example, and describe the two-level test strategy that covers it.

AWhen is adding a repository layer not worth it, and how do you decide for a new system?design

In small apps with few rules, a stable data-access choice, and tests that can use a real database, a repository adds files without removing a cost; the DbContext can be used directly. Add repositories where rules need protecting, data access may change, or tests need fakes, and keep the decision reversible by keeping database code out of the core.

How to answer:

Give criteria rather than a yes or no, connect them to costs (change, testing, complexity), and show how a layered structure lets you add the pattern later without a rewrite.

Web API

HTTP basics

FWhat are a client and a server?concept

A client is a program that sends requests, such as a browser or a mobile app. A server is a program that waits for requests and answers them, such as our ASP.NET Core API. In the SMS, the teacher's browser is the client and the API is the server.

FWhat is an API?concept

An API (Application Programming Interface) is a set of addresses that other programs call to read or change data. A Web API works over HTTP and usually exchanges JSON. For example, GET /api/classes/10/sections/A/students returns the students of Class 10-A.

FWhat do the HTTP status codes 200, 201, 400, 404 and 500 mean?concept

200 OK means the request worked. 201 Created means something new was saved. 400 Bad Request means the client sent invalid data, 404 Not Found means the item does not exist, and 500 Internal Server Error means the server failed. Codes starting with 2 are success, 4 are client errors, 5 are server errors.

MWhat is the difference between GET and POST?concept

GET reads data, has no body, and is safe to repeat; browsers may cache or bookmark it. POST creates something new and sends data in the body; repeating it can create duplicates. Never change data with GET, because a refresh or a link preview could repeat it.

MWhat does it mean that HTTP is stateless, and how does the server know who is calling?concept

Stateless means each request stands alone; the server does not remember earlier requests. So every request must carry the caller's identity, usually a token in the Authorization header or a cookie. The API validates that token on every request.

MWalk me through what happens when a teacher opens the class list.concept

The browser sends a GET request with the class filter and the login token. The API checks the token and the teacher's permission, runs the C# logic, and queries the database for the enrolled students. SQL Server returns the rows, the API converts them to JSON with status 200, and the browser displays the list.

HTTP and REST

FWhat are the parts of an HTTP request and an HTTP response?concept

A request has a method and URL, headers, and an optional body. A response has a status line with a status code, headers, and an optional body. For example, POST /api/students with a JSON body got 201 Created, a Location header, and the new student as JSON.

FWhat is the difference between 400 and 409, and between 401 and 403?concept

400 Bad Request means the request itself is wrong, such as an empty name; sending it again unchanged fails again. 409 Conflict means the request is valid but clashes with the current state, such as issuing a book with no free copy. 401 means "not signed in"; 403 means "signed in, but not allowed".

FWhat is a query string, and when do you use it instead of a path segment?concept

The part of a URL after ?, with name=value pairs joined by &. Use the path to identify a resource, such as /api/students/3, and the query string for options on it, such as paging, sorting, or filtering: /api/students?page=2&pageSize=20.

MWhat do safe and idempotent mean for HTTP methods?concept

Safe methods change nothing on the server, such as GET. Idempotent methods have the same effect whether sent once or many times: GET, PUT, and DELETE are; POST is not. Deleting student 4 twice returned 204 then 404, but student 4 was gone either way.

MWhat is the difference between PUT and PATCH?concept

PUT replaces the whole resource with the body sent, so missing fields are treated as cleared, and sending it twice gives the same result. PATCH changes only the fields sent; whether it is idempotent depends on the change, such as "add 1" versus "set to 5".

MWhat makes an API RESTful? Give examples of good and bad paths.design

Resources with their own addresses, nouns in paths and verbs in methods, plural collections, children under parents, statelessness, and status codes that report the result. Good: GET /api/students/3/fee-invoices. Bad: POST /api/getFeeInvoicesForStudent?id=3.

SA mobile app shows success for failed fee payments. The API returns 200 with an error message in the body. What do you change?scenario

Return status codes that match the result: 400 for invalid input, 404 for a missing invoice, 409 for a conflict such as an already-paid invoice, and 2xx only for real success. Put details in a standard error body. Clients that check only the status code then behave correctly without changes.

How to answer:

Explain why status codes are the contract every client and tool reads, map each failure to a code, and mention a standard error format (ProblemDetails, Lesson 74) and versioning if clients depend on the old behaviour.

SA parent double-clicks 'Pay'. How do you stop two payments when POST is not idempotent?design

Make the operation idempotent: the client sends a unique idempotency key with the request, and the server stores it with the payment and returns the first result for any repeat with the same key. Disable the button after the first click too, but never rely on the client alone.

How to answer:

Name the problem (non-idempotent POST), describe idempotency keys with a unique constraint in the database, and add the UI and concurrency safeguards as extra layers.

AWhy does statelessness matter when an API must serve many schools and users?design

When each request carries everything needed, such as identity in a token and the ids in the URL, any server can handle any request. You can add servers behind a load balancer, restart one without losing sessions, and cache responses. Server-side session state ties users to one machine and limits scaling.

How to answer:

Connect statelessness to horizontal scaling, resilience, and caching, and say where state goes instead: the client, tokens, the database, or a distributed cache.

ASP.NET Core project

FWhat is Kestrel?concept

The cross-platform web server built into ASP.NET Core. It runs inside your application, so dotnet run alone can serve HTTP requests. In production it can face the internet directly or sit behind a reverse proxy such as IIS, Nginx, or a cloud load balancer.

FWhat are the two halves of Program.cs in an ASP.NET Core app?concept

Before builder.Build(), services are registered with builder.Services.Add..., such as controllers and OpenAPI. After it, the request pipeline is built with app.Use... and app.Map..., and app.Run() starts the server. Services cannot be added after Build().

FWhat is a controller, and what is an action?concept

A controller is a class, usually deriving from ControllerBase, that handles requests for one resource, with a route such as [Route("api/school")]. An action is a public method in it with an HTTP attribute such as [HttpGet]; it runs for the matching method and path.

MWhat is launchSettings.json for, and is it used in production?concept

It holds launch profiles for running the app on a developer's computer: URLs and ports, and environment variables such as ASPNETCORE_ENVIRONMENT=Development. It is not used in production; servers set the environment and URLs through their own configuration.

MHow does the hosting environment change an app's behaviour, and what is the default?concept

ASPNETCORE_ENVIRONMENT sets it, and code checks it with app.Environment.IsDevelopment(), to show tools such as the OpenAPI document only while developing; settings files can differ per environment too. When it is not set, the environment is Production, so development features stay off by default.

MWhy does an app log 'Failed to determine the https port for redirect'?scenario

UseHttpsRedirection wants to send HTTP requests to HTTPS, but the app has no HTTPS endpoint, for example when started with the http launch profile. It lets the request through and logs the warning. With an HTTPS endpoint configured, HTTP requests get a 307 redirect instead.

SEvery request to a new API returns 404, though the controller and route look correct. What do you check?scenario

That AddControllers() registers controllers and MapControllers() is in the pipeline, that the controller is public with [ApiController] and a [Route], that the action has the right HTTP attribute, and that the URL, including the api/ prefix and port, matches. Logging at Information level for routing shows which endpoint, if any, matched.

How to answer:

Work from the outside in: the right app and port, the pipeline, the registration, then the route template. Name the logging you would switch on to confirm.

SHow would you structure a Web API solution so the API project stays thin?design

The API project holds only HTTP concerns: controllers, middleware, configuration, and the composition root. Business rules and entities live in a core project, and data access in a data project, both referenced by the API. Controllers translate HTTP to service calls and results back to HTTP.

How to answer:

Describe the projects and their references, what belongs in each, and why it keeps rules testable without HTTP. Relate it to the layers from the repository pattern lesson.

AWhat decides how an ASP.NET Core API is hosted in production, and what must differ from development?design

The hosting model: Kestrel directly, behind a reverse proxy, in a container, or on a managed platform, chosen for TLS termination, scaling, and operations needs. In production the environment is Production, development tools such as OpenAPI UIs are off or protected, HTTPS is enforced, URLs come from server configuration, and secrets come from a secure store, never source files.

How to answer:

Cover hosting options with trade-offs, then a checklist of what changes between environments, and how configuration is supplied per environment.

Middleware

FWhat is middleware in ASP.NET Core?concept

A step in the request pipeline. Each middleware receives the HttpContext and the next step; it can run code before calling next, stop the request, or run code after the rest of the pipeline returns. Logging, HTTPS redirection, authentication, and error handling are all middleware.

FWhat is the difference between app.Use and app.Run(delegate)?concept

app.Use adds a middleware that receives the next step and normally calls it. app.Run with a delegate adds a terminal step that never calls a next one. app.Map starts a separate branch for a path prefix. (app.Run() with no arguments, at the end of Program.cs, starts the server.)

FWhat does short-circuiting mean in the middleware pipeline?concept

A middleware writes the response itself and does not call the next step, so the rest of the pipeline, including the controller, never runs. The earlier middleware still run their "after" code. Authentication answering 401, or a stock-taking check answering 503, are examples.

MHow do you write a custom middleware class?coding

A class whose constructor takes RequestDelegate next (plus singleton services such as a logger) and which has public async Task InvokeAsync(HttpContext context) that calls await _next(context). Register it with app.UseMiddleware<T>(), usually through an extension method such as app.UseRequestTiming().

MWhy can't a middleware add a header after calling next, and what do you do instead?coding

Once the action starts writing the body, the headers have been sent, and changing them throws "Headers are read-only, response has already started". Set headers before calling next, or register context.Response.OnStarting(...), which runs just before the headers go out.

MWhat is the usual order of the built-in middleware, and why?concept

Exception handling first, so it wraps everything; then HTTPS redirection, static files, routing and CORS, authentication, authorization, and finally the endpoints. Each step needs what the earlier ones did: authorization needs the user that authentication found.

SAfter a cleanup of Program.cs, every signed-in user gets 401. What would you look at first?scenario

The middleware order: UseAuthorization() placed before UseAuthentication() checks requests before any token has been read, so every caller looks anonymous. Restore the order, document why each middleware sits where it does, and add a test that signs in and calls a protected endpoint.

How to answer:

Go from symptom to the pipeline, explain the dependency between the two steps, and add the regression test so the order is protected.

SIn an app built with WebApplication, does it matter where MapControllers() appears relative to app.Use calls?concept

Not for when the endpoints run: MapControllers() only registers them, and WebApplication runs the endpoint middleware at the end of the pipeline, after every Use... call. A middleware added after MapControllers() still runs before the controller. The order of the Use... calls among themselves still matters.

How to answer:

Explain the implicit routing and endpoint middleware WebApplication adds, describe how you would verify it, and note that keeping Map calls last is still the readable convention.

AHow do you decide between middleware, filters, and code in the action for a cross-cutting concern?design

Middleware for concerns that apply to every HTTP request, even unmatched ones: timing, error handling, security headers, rate limiting. Filters for concerns tied to actions and their metadata: validation, per-action caching, action-level authorization. The action only for logic specific to that endpoint. Keep business rules out of all three, in the core layer.

How to answer:

Give the scope each mechanism sees, a concrete example for each, and the cost of putting a concern at the wrong level, such as running database work for every 404.

Controllers and minimal APIs

FWhat is the difference between a controller and a minimal API endpoint?concept

A controller is a class deriving from ControllerBase, with action methods routed by attributes and services injected through its constructor. A minimal API endpoint is a function mapped in code with app.MapGet and similar, receiving services as parameters. Both run on the same pipeline.

FWhat is a route parameter, and how does it reach the action?concept

A part of the route template in braces, such as {admissionNumber} in api/students/{admissionNumber}. ASP.NET Core takes that part of the URL and passes it to the action parameter with the same name, converting the type if needed.

FWhat does 405 Method Not Allowed mean, and how is it different from 404?concept

405 means the path exists but not for that HTTP method, such as POST to a GET-only route; the Allow header lists the methods that work. 404 means no route matches the path at all.

MWhat does the [ApiController] attribute do?concept

It makes attribute routing required, returns 400 automatically when model validation fails, applies binding source rules (complex types from the body), and turns error results such as NotFound() into ProblemDetails JSON. Without it, a controller behaves like an MVC controller.

MWhy return ActionResult<T> instead of IActionResult?coding

ActionResult<T> lets the action return either a T, which becomes 200 OK, or another result such as NotFound(), with less code. It also keeps the success type visible to tools, so the OpenAPI document describes the response body. IActionResult loses that type information.

MWhy did the controller and the minimal API return different 404 responses for the same missing student?scenario

[ApiController] converts NotFound() into a ProblemDetails body with type, title, status, and traceId, while the minimal API's Results.NotFound() sends an empty body. To make errors consistent, register ProblemDetails for the whole app so every error uses the same shape.

SWhat belongs in a controller action, and what does not?design

The action reads the request, calls a service, and turns the result into an HTTP response, such as 200 with a DTO or 404. Business rules, SQL, and entity mapping do not belong there: they go in the core services and the data layer, where they can be tested without HTTP.

How to answer:

Describe thin controllers and the reasons: testability, reuse across endpoints and other hosts, and keeping HTTP concerns in one layer. Give a concrete example of a rule that would be duplicated.

SA minimal API project's Program.cs has grown to 2,000 lines. How do you restructure it?scenario

Move each resource's endpoints into its own static class with an extension method such as MapStudentEndpoints(this IEndpointRouteBuilder app), using MapGroup("/api/students") for the shared prefix and settings. Move handler bodies into named methods so they can be tested. Program.cs then only calls one Map method per resource.

How to answer:

Give the structure, the grouping feature, and how it improves merges and tests; note that switching to controllers is not required to fix it.

AHow would you choose between controllers and minimal APIs for a new product, and how would you keep the choice reversible?design

Weigh the number of endpoints, team experience, the need for filters and conventions, and existing code. Controllers suit large APIs and teams used to them; minimal APIs suit small focused services. Keep endpoints thin and rules in services, use one error format and one validation approach, and the endpoint layer can be rewritten without touching the rest.

How to answer:

Make it a decision with criteria and a written record, and show that a layered design limits the cost of changing it later.

Dependency injection

FWhat is dependency injection?concept

A technique where an object receives the services it needs, usually through its constructor, instead of creating them itself. In ASP.NET Core a built-in container creates them: StudentsController asks for a StudentService and gets one, with its repository and DbContext built for it.

FWhat is the difference between singleton, scoped, and transient lifetimes?concept

Singleton: one object for the whole application. Scoped: one object per request, shared inside it. Transient: a new object every time one is requested. In the demo, the singleton id never changed, the scoped id changed per request, and transient ids differed even within one request.

FWhich lifetime should a DbContext have, and why?concept

Scoped, which AddDbContext uses by default. A DbContext tracks the entities of one unit of work and is not thread-safe, so each request needs its own, shared by the repositories and services handling that request, and disposed when the request ends.

MWhat is a captive dependency, and how does ASP.NET Core help you catch it?concept

A shorter-lived service held by a longer-lived one, such as a singleton whose constructor takes a scoped DbContext: the context then lives forever and is shared by every request. In Development, scope validation stops the app at startup with "Cannot consume scoped service ... from singleton". It is off in Production by default.

MWhy is the 'Unable to resolve service' error for a controller found only at request time?scenario

Controllers are not registered in the container; ASP.NET Core creates them when a request needs one, resolving their constructor parameters then. So startup validation does not see that a controller's dependency is missing. Tests that call every endpoint catch it before users do.

MWhy prefer constructor injection over resolving services from IServiceProvider inside methods?concept

Constructor injection makes every dependency visible in one place, lets the container validate them, and lets tests pass fakes directly. Resolving from IServiceProvider or HttpContext.RequestServices (the service locator pattern) hides dependencies and couples code to the container.

SParents occasionally see another parent's data at busy times. You suspect dependency injection. What do you look for?scenario

Singletons that hold per-request state, such as a current-user helper or a cache keyed by nothing, and singletons that capture scoped services. Check registrations for state and lifetimes, make per-request state scoped, keep singletons stateless or thread-safe, and add a concurrency test that runs two users in parallel.

How to answer:

Explain why the bug appears only under concurrency, list the suspicious registration patterns, and give the fix and a way to prove it.

SA singleton background service needs to read the database. How do you give it a DbContext safely?coding

Inject IServiceScopeFactory, create a scope for each piece of work with CreateAsyncScope(), resolve the DbContext or repository from that scope, and dispose the scope when the work ends. Each run then gets a fresh context, as a request would, instead of one captive context for the life of the app.

How to answer:

Name the captive dependency risk, show the scope-per-unit-of-work pattern, and mention IDbContextFactory as an alternative when only a context is needed.

AHow would you organise service registration in a solution with many projects?design

Each project registers its own types through one extension method, such as AddSchoolData(connection), so the host's Program.cs composes projects, not individual classes. Register interfaces to implementations, choose lifetimes deliberately, keep scope validation on in development and CI, and test that every endpoint resolves.

How to answer:

Cover ownership of registrations, the composition root, how lifetimes are reviewed, and automated checks. Mention keeping Core free of container packages if it should stay framework-neutral.

Configuration

FWhere does an ASP.NET Core app read its configuration from, and in what order?concept

By default: appsettings.json, then appsettings.{Environment}.json, then user secrets in Development, then environment variables, then command-line arguments. A later source overrides an earlier one for the same key.

FHow do you read a connection string in ASP.NET Core?coding

Put it under ConnectionStrings in configuration, such as ConnectionStrings:SchoolDb, and read it with builder.Configuration.GetConnectionString("SchoolDb"). Check that it is not null or empty at startup, and keep passwords out of committed files.

FWhat are user secrets, and when should you use them?concept

A per-user JSON file outside the project folder, linked by the project's UserSecretsId, for local development secrets such as your own connection string. They never reach Git and load only in the Development environment. They are not encrypted and not for servers.

MHow do you set a nested configuration key with an environment variable?coding

Replace each : with a double underscore: School__CurrentAcademicYear=2027-28 sets School:CurrentAcademicYear. The colon is not valid in environment variable names on every operating system; on the command line, --School:Name=... keeps the colon.

MWhat is the options pattern, and why use it instead of reading IConfiguration directly?concept

It binds a configuration section to a class, such as SchoolOptions, registered with AddOptions<T>().BindConfiguration("School") and injected as IOptions<T>. It gives typed values, one place for defaults and validation, and classes that do not depend on configuration keys.

MWhat is the difference between IOptions, IOptionsSnapshot, and IOptionsMonitor?concept

IOptions<T> reads the value once for the app's life. IOptionsSnapshot<T> is scoped and reads a fresh value each request, so file changes appear without a restart. IOptionsMonitor<T> is a singleton with the current value and change notifications, for long-lived services.

SA deployment used a wrong page size setting and broke a screen two days later. How do you catch such errors earlier?scenario

Bind settings to options classes with validation attributes, and call ValidateDataAnnotations() and ValidateOnStart(). The app then refuses to start with a message naming the setting, so the deployment fails at once and the previous version keeps serving. Add custom Validate rules for checks attributes cannot express.

How to answer:

Explain fail-fast configuration, how it interacts with deployment health checks, and give an example of the message an operator would see.

SA developer committed a production connection string with a password to Git. What do you do?scenario

Treat it as leaked: change the password immediately, check access logs, and only then remove it from the history if needed. Then fix the cause: production secrets come from environment variables or a secret store, local ones from user secrets, and a secret scanner runs on every push.

How to answer:

Order matters: rotate first, then clean up, then prevent. Mention that deleting the line does not remove it from history or from clones.

AHow would you design configuration and secret management for an API deployed to several environments?design

One build for all environments; safe defaults in appsettings.json; environment differences in environment files or host settings; secrets in a managed secret store, injected at startup with managed identities rather than stored passwords; options classes validated on start; and settings changes reviewed and versioned like code.

How to answer:

Cover the build-once principle, where each kind of value lives, how secrets are accessed without credentials, validation, and auditing changes.

OpenAPI

FWhat is OpenAPI, and how is it related to Swagger?concept

OpenAPI is a standard format, in JSON or YAML, that describes an HTTP API: paths, methods, parameters, bodies, responses, and data shapes. It was originally called the Swagger specification; Swagger is now the name of a family of tools around it, such as Swagger UI.

FWho uses an API's OpenAPI document?concept

Front-end and mobile developers to learn routes and fields, code generators to create typed clients, testers and test tools to know every status code, API gateways to import routes, and the API team itself as a reference and contract.

FHow do you add descriptions to an ASP.NET Core API's OpenAPI document?coding

Write /// XML comments on actions, with <summary>, <param>, and <response>, and set GenerateDocumentationFile to true in the project file. In .NET 10, the OpenAPI package reads the generated XML file and adds the text to the document.

MWhat does [ProducesResponseType] do, and what is the common mistake with it?coding

It declares a status code, and optionally a body type, that an action can return, so the OpenAPI document lists it. Once any response is declared, the success response is no longer inferred: declaring only 404 removed the 200. Declare every response, including the success one.

MHow do you change the document's title, or hide an endpoint from it?coding

Register a document transformer in AddOpenApi(options => options.AddDocumentTransformer(...)) and set document.Info.Title. Hide a controller or action with [ApiExplorerSettings(IgnoreApi = true)]; hiding does not protect it, so secure the endpoint separately.

MWhy does an integer field appear as type integer or string in an ASP.NET Core OpenAPI document?concept

ASP.NET Core's web JSON defaults allow reading numbers from strings, such as "3", so the schema honestly lists both types with a number pattern. Clients normally send numbers; change the JSON number handling if a client generator copes badly with it.

SWhich API changes are breaking for clients, and how do you catch them before release?design

Breaking: removing or renaming a response field, changing a field's type, adding a required request field, removing an endpoint or changing its meaning. Usually safe: adding endpoints or optional fields. Generate the OpenAPI document in the build and compare it with the previous version in every pull request, failing the build on breaking differences.

How to answer:

Give examples on both sides, then describe automated contract comparison and what you do when a breaking change is unavoidable (versioning, deprecation period).

SShould the OpenAPI document and a documentation page be available in production?design

Only as a deliberate decision. Public APIs often publish them, sometimes behind authentication; internal APIs may expose them only inside the network or not at all. Never expose them by accident, and never rely on hiding endpoints from the document as security.

How to answer:

Weigh discoverability for partners against exposing the attack surface, and describe controls: environment checks, authentication, or publishing a static copy of the document instead.

AHow would you use OpenAPI to keep a mobile app and an API in step across several teams?design

Treat the document as the contract: generate it from the API in CI, publish each version, generate the mobile client from it, and compare versions to detect breaking changes. Require complete response declarations and descriptions in review, and version the API when a break is necessary.

How to answer:

Cover generation, publication, client generation, contract checks, and versioning, and the team agreements that make it work, such as reviewing document diffs.

Routing

FWhat is a route template?concept

A pattern for request paths, made of literal segments and parameters in braces, such as api/students/{admissionNumber}. Routing matches the request's path and method against the templates and passes parameter values to the action.

FHow do a controller's [Route] and an action's [HttpGet] combine?concept

The controller's route is a prefix and the action's template is added to it. [Route("api/students")] with [HttpGet("{admissionNumber}")] gives GET api/students/{admissionNumber}; [HttpGet] alone gives GET api/students.

FWhen should a value go in the path, and when in the query string?design

In the path when it identifies the resource or its place in a hierarchy, such as an admission number or a class and section. In the query string when it is an option on a list: paging, filtering, or sorting, such as ?page=2&pageSize=20.

MWhat are route constraints, and what happens when one fails?concept

Rules on a route parameter, such as int, range(1,10), or length(1,2), that decide whether the route matches. When one fails, the route does not match, and the client gets 404 with no explanation, before any action runs. They are for matching, not for validation.

MHow do you read and validate optional query string values in a controller?coding

Add parameters with [FromQuery] and default values, such as int page = 1, and put validation attributes on them, such as [Range(1, 100)]. With [ApiController], an invalid value returns 400 ValidationProblemDetails naming the parameter, and the action never runs.

MWhat happens when two routes could match the same request?concept

The more specific template wins: a literal over a parameter, a constrained parameter over an unconstrained one, so /api/students/3 chose {id:int} over {admissionNumber}. If two are equally specific, the request fails with an ambiguous match error (500), which must be fixed in the routes.

SA list endpoint returns all 9,000 students and the mobile app is slow. How do you redesign it?scenario

Add paging with page and pageSize in the query string, a maximum page size, a stable sort ending with the key, and a response that includes the total count. Add filters such as sectionId so clients ask only for what the screen shows, and project to DTOs with only the needed fields.

How to answer:

Cover the request shape, the response shape, limits, sorting stability, filtering, and the database side (indexes, projection). Mention keeping old clients working while they move to the paged version.

SHow would you design routes for students, their guardians, and their fee invoices?design

/api/students for the collection and /api/students/{id} for one student; /api/students/{id}/guardians and /api/students/{id}/fee-invoices for related collections; and /api/fee-invoices/{invoiceNumber} for an invoice by its own key. Keep nesting to two parent levels, use plural lowercase nouns with hyphens, and put filters in the query string.

How to answer:

Explain the reasoning for each choice: ownership, unique keys, depth limits, and consistency, and how the routes appear in the OpenAPI document.

AOffset paging with page numbers slows down on very deep pages. What alternative would you consider?design

Keyset (cursor) paging: the client sends the last key it saw, and the query asks for rows after it, such as WHERE (LastName, FirstName, Id) > (@last...), which an index can seek directly. It stays fast at any depth and is stable when rows are added, but it cannot jump to page 400; keep offset paging for screens that need page numbers.

How to answer:

Explain why OFFSET reads and discards rows, describe keyset paging and its index needs, and choose per use case: infinite scroll and exports versus numbered pages.

Model binding and validation

FWhat is model binding in ASP.NET Core?concept

Turning request data into action parameters: route values, query string values, the JSON body, headers, and services. With [ApiController], a complex type such as CreateStudentRequest is read from the body, and simple types from the route or query string.

FHow do you add validation rules to a request model?coding

With data annotation attributes such as [Required], [StringLength(50)], [Range], and [RegularExpression] on its properties or record parameters. With [ApiController], invalid requests get 400 with ValidationProblemDetails before the action runs.

FWhat does CreatedAtAction return, and why use it?coding

A 201 Created response with the new resource as the body and a Location header built from another action's route, such as the GET for one student. Building the URL from the route keeps it correct when routes change, unlike a hand-written string.

MHow do you validate a rule that compares two fields?coding

Implement IValidatableObject on the request type and return ValidationResult objects from Validate, naming the fields involved, such as an age rule over DateOfBirth and AdmissionDate. ASP.NET Core calls it only after every attribute has passed.

MWhy might a JSON enum value like "Male" fail to bind, and how do you fix it?concept

System.Text.Json reads and writes enums as numbers by default, so a name cannot be converted and the request gets 400. Register JsonStringEnumConverter in the JSON options so enums travel as names, which are clearer and stay stable when enum values are reordered.

MIn what order are binding and validation checks applied, and why does it matter?concept

Content type (415 if not JSON), then binding (400 for values that cannot be converted, stopping at the first), then attributes (every failing field), then IValidatableObject, then the action. Each step runs only if the previous passed, so clients may need two attempts to see all kinds of errors.

SWhere should validation live: the API request model, the domain, or the database?design

In all three, for different purposes. The request model checks shape and format and gives clients clear 400 errors. The domain enforces business rules for every caller, not just the API. Database constraints are the last guard against any client or bug. Duplicated rules are acceptable when each layer has its own reason.

How to answer:

Explain what each layer can see, give SMS examples for each, and how you keep messages consistent, such as mapping domain errors to ProblemDetails.

SA mobile app sends dates like 12/04/2016 and some records are wrong. What do you change?scenario

Accept only an unambiguous format, ISO 8601 (2016-04-12), which DateOnly binds directly, and reject anything else with a 400 that names the field. Fix the app to send ISO dates, and check existing data for swapped day and month values.

How to answer:

Identify the ambiguity, enforce a strict contract, communicate it in the OpenAPI document, and plan the data repair.

AHow would you design input validation and error reporting for a large API used by several client teams?design

One request DTO per operation with declarative rules, cross-field rules in IValidatableObject or a validation library, one error format (ValidationProblemDetails with stable keys and messages), rules visible in the OpenAPI document, and tests for each rule. Keep business rules in the domain and map their errors to the same format.

How to answer:

Cover consistency, documentation, localisation of messages if needed, and how clients can rely on error keys. Mention when a library like FluentValidation is worth it.

Responses and errors

FWhat is ProblemDetails?concept

A standard JSON format for HTTP error responses (RFC 9457), with type, title, status, detail, and instance, plus your own extension fields such as errorNumber. ASP.NET Core can produce it for every error, so clients parse one shape everywhere.

FWhich status code should a successful POST that creates a resource return?concept

201 Created, with a Location header giving the new resource's address and, usually, the resource in the body. In a controller, CreatedAtAction builds both from another action's route.

FWhy should an API not return exception details in a 500 response?concept

Stack traces and messages reveal file paths, library versions, SQL, and internal names that help attackers, and they mean nothing to users. Return a general ProblemDetails with a traceId, and write the full exception to the server log.

MWhen would you return 400, 409, and 422?concept

400 when the request is malformed or fails field validation. 409 when a valid request conflicts with the current state, such as a duplicate admission number or a record changed by someone else. 422 when a well-formed request breaks a business rule, such as paying more than the balance.

MHow do you handle exceptions globally in ASP.NET Core 8 and later?coding

Register AddProblemDetails() and one or more IExceptionHandler classes with AddExceptionHandler<T>(), and put app.UseExceptionHandler() first in the pipeline. Each handler's TryHandleAsync returns true for exceptions it answers; anything unhandled becomes a 500 ProblemDetails.

MWhat does UseStatusCodePages add when ProblemDetails is registered?concept

It fills empty error responses, such as a 404 from a failed route constraint, with a ProblemDetails body. Without it, those responses have no body, so clients see two different error shapes.

SA client retries every failed payment three times. Some failures can never succeed. What do you change in the API?scenario

Return 4xx codes for client-side and rule failures, such as 422 for amount above balance and 409 for conflicts, so the client knows retrying is pointless, and 5xx only for real server failures, which may be retried. Include a machine-readable errorNumber, and make payments idempotent so a retried request cannot charge twice.

How to answer:

Explain status codes as instructions for client behaviour, give the mapping, and mention idempotency keys for safe retries of money operations.

SShould controllers catch domain exceptions with try/catch? What is the alternative?design

Usually not: repeated try/catch blocks drift apart and hide the action's real work. Let domain exceptions carry a meaning, such as an error number, and translate them in one place: an IExceptionHandler that maps them to status codes and ProblemDetails. Use controller helpers only for outcomes the controller decides itself, such as not found.

How to answer:

Contrast the two approaches with an example, and mention testing the mapping once and keeping the domain free of HTTP concepts.

AHow would you design an API's error contract for many client teams over several years?design

One format (ProblemDetails) for every error; a documented catalogue of stable error codes, such as the SMS's 500xx numbers, each with its HTTP status; codes and status listed in the OpenAPI document; human messages that may change and machine codes that never do; a traceId for support; and versioning rules for adding codes without breaking clients.

How to answer:

Separate what clients may depend on (status, code) from what may change (text), show where the catalogue lives, and how it is tested and documented.

FWhat is an API response wrapper (envelope), and why do client teams ask for one?concept

A fixed outer shape for every response body, such as status, message, and data. A client can then read every endpoint with one piece of code: check status, show message, use data. Without it, each endpoint and each kind of error can have its own shape, and every app needs special parsing for each.

FIf every response has a status field, why keep using HTTP status codes?concept

Browsers, proxies, load balancers, monitoring, and retry logic read the HTTP status code, never the JSON body. Answering 200 with "status": "error" hides every failure from them. In the SMS, a missing student is still 404 and a broken rule still 422; the wrapper only changes the body.

FWhy does the SMS DELETE endpoint answer 200 with a message instead of 204 No Content?concept

A 204 response can never have a body, so it cannot carry the wrapper. With an envelope, every answer has a body, so a successful delete answers 200 with ApiResponse.Ok("Student ADM-2026-10001 was removed.") and no data.

MHow can a C# design guarantee that an error response never contains data?coding

Use two classes: a base ApiResponse with status, message, errorCode, errors, and traceId, and ApiResponse<T> that adds Data. The Fail method returns the base class, so an error object has no Data property at all, and the JSON cannot contain one even by mistake.

MWhich error paths in ASP.NET Core must be changed so that every error uses the wrapper?coding

Four: exceptions you expect (an IExceptionHandler for SchoolRuleException), every other exception (a last IExceptionHandler that answers 500), automatic validation errors (ApiBehaviorOptions. InvalidModelStateResponseFactory), and empty error responses such as unknown routes or 405 (UseStatusCodePages with a handler). Also set SuppressMapClientErrors, or a bare NotFound() still becomes a ProblemDetails.

MWhat is a traceId in an error response, and how is it used?concept

The id of the request's trace (Activity.Current.Id in ASP.NET Core). The client gets it in the error response; the server logs the real exception under the same id. Support asks the user for the traceId and finds the exact log entry, without the response ever exposing exception details.

SAfter adding an IExceptionHandler for 500s, production crashes no longer appear in the logs. What happened, and how do you fix it?scenario

Since .NET 10, the exception handler middleware does not write its own log entry when an IExceptionHandler returns true. The handler answered the client but nobody logged the exception. Fix it by logging inside the handler with ILogger, including the same traceId the response carries, and add a test or check that a crash produces a log entry.

How to answer:

Start from the symptom, name the framework behaviour change, give the fix (log in the handler with the traceId), and say how you would stop it happening again.

SYour team is split: some want a response envelope, others want plain bodies with ProblemDetails (RFC 9457) for errors. How do you decide?design

ProblemDetails is a standard: tools, gateways, and generated clients understand it, and success bodies stay plain. An envelope gives one shape for success and error, which many front-end and mobile teams prefer, but it is a house format that every client must learn. Decide by who consumes the API: public or partner APIs lean to standards; one team's own apps often lean to an envelope. Either way, keep real status codes, never leak exception details, and document it in OpenAPI. The SMS chose an envelope for its own apps and keeps the same status codes.

How to answer:

Compare both on standards, tooling, and client simplicity, tie the choice to the API's consumers, and name what must stay true in both designs.

AMany services each have their own response format, and clients struggle. How would you standardise the response contract across them?design

Agree one contract (envelope or ProblemDetails) and publish it as a small shared library with the common Ok and Fail methods, the error handlers, and the validation setup, so services adopt it with a few lines. Define error codes per domain, require a traceId linked to distributed tracing, describe the shapes in each OpenAPI document, and add contract tests that call every endpoint's error paths. Roll it out with API versioning, so existing clients keep the old shape until they move.

How to answer:

Cover the contract, how teams adopt it cheaply, how it is enforced (tests, OpenAPI), observability, and a migration plan that does not break existing clients.

Building endpoints

FWhat does CRUD mean, and which HTTP methods does each part use?concept

Create, read, update, and delete: the basic operations on a record. In a REST API, create is POST, read is GET, update is PUT or PATCH, and delete is DELETE, each on a resource address such as /api/students/{admissionNumber}.

FWhat is a soft delete, and why use it for students?concept

Marking a record as deleted, such as IsDeleted = 1 with a timestamp, instead of removing the row. Students have invoices, payments, attendance, and marks; removing the row would break that history or be refused by foreign keys. A query filter hides soft-deleted rows everywhere.

FWhat status codes should PUT and DELETE return?concept

PUT: 200 with the updated resource, or 204 with no body; 400 for invalid input; 404 when the resource does not exist. DELETE: 204 when removed; 404 when there is nothing to remove, including a second delete of the same resource.

MHow would you implement optional search and filter parameters on a list endpoint with EF Core?coding

Start from the IQueryable, add a Where only for each parameter that was given, then count, sort, and page. EF Core turns it into one parameterised SQL query; StartsWith becomes LIKE 'text%', which can use an index, and a related-table filter becomes EXISTS.

MWhat is an EF Core SaveChanges interceptor, and what would you use one for?coding

A class EF Core calls during SaveChanges, such as before the SQL is sent. It can inspect and change tracked entities, for example setting UpdatedAt on every modified entity with audit columns, so no repository or service has to remember to do it.

MWhy is a uniqueness check in code not enough, even when it runs before every insert?concept

The check cannot see rows hidden by filters, such as soft-deleted records, and two requests can both pass it at the same moment before either inserts. Only the database sees every row at insert time, so keep a UNIQUE constraint and translate its error (2627 or 2601) into a clear 409.

SA school asks to permanently delete a student's data on request. How does that fit with soft delete?scenario

Soft delete covers normal removals. A permanent erasure request is a separate, audited process: check legal retention rules for fee and academic records, anonymise or remove personal fields while keeping financial and statistical records that must stay, record who approved it, and run it in a transaction.

How to answer:

Distinguish routine removal from data-protection erasure, mention retention obligations, anonymisation, auditing, and backups that also hold the data.

SWhen would you add PATCH to an API that already has PUT?design

When clients often change one or two fields of a large resource, when several clients edit different fields of the same record, or when sending every field risks overwriting newer data. Use a clear format, such as JSON Merge Patch or JSON Patch, validate the result after applying it, and combine it with a concurrency check.

How to answer:

Weigh payload size and lost-update risk against complexity, name the patch formats, and explain validating the patched result rather than the patch itself.

AHow would you design search for a system with millions of students across many schools?design

Prefix searches on indexed name and number columns for the common cases, always scoped by school and paged with a stable sort. For "contains", spelling mistakes, or several fields at once, use full-text search or a dedicated search engine fed by changes from the database, and keep the API contract the same whichever engine answers.

How to answer:

Start from the query patterns, show the index each needs, explain where LIKE stops scaling, and how a search engine is kept in sync.

FWhat is master data, and how is it different from transaction data?concept

Master data is reference information that other features depend on, read constantly and changed rarely, such as academic years, classes, sections, and subjects. Transaction data records daily activity, changes constantly, and grows large, such as attendance, marks, and payments.

FWhat does the Cache-Control header with max-age do?concept

It tells clients and caches how long they may reuse a response without asking the server again, such as Cache-Control: public,max-age=3600 for one hour. In ASP.NET Core, [ResponseCache(Duration = 3600)] adds it; the server itself stores nothing.

FWhy return classes together with their sections in one response?design

Screens almost always need both. Returning them nested saves the client from making one more request per class, the N+1 problem on the client's side, and EF Core can build the whole tree with one SQL query.

MWhy should error responses never be cached, and what does ASP.NET Core do about it?concept

A cached error, such as a 404 for the current academic year, could be shown long after the problem was fixed. ASP.NET Core's exception handling adds Cache-Control: no-cache,no-store to the error responses it writes, so clients and proxies do not keep them.

MHow do you choose a max-age for an endpoint?design

By how long the data may be stale without harm. Subjects and academic years can be an hour or more; classes with live student counts a few minutes during admissions; attendance or balances not at all. When in doubt, start short and lengthen it after watching how the data changes.

MWhat does the EF Core warning about a global query filter on the required end of a relationship mean?concept

A principal entity, such as Student, is filtered, but a dependent that requires it, such as Enrollment, is not. Queries on the dependent then still return rows whose principal is hidden, such as enrollments of removed students being counted. Give the dependent a matching filter through its navigation, or make the relationship optional.

STwo subjects, Maths and Mathematics, exist and marks are split between them. How do you fix it and prevent it?scenario

Merge them: choose one, move every mark, exam paper, and allocation to it in one transaction, then remove the other. Prevent it with unique constraints on both the code and the name, translated into a 409, and restrict master data changes to administrators.

How to answer:

Cover the data repair, its transaction and verification, the constraints, the API's answer, and the permission rule.

SAn app loads the same subject list thousands of times each morning. What can the API do?scenario

Send Cache-Control with a suitable max-age so clients reuse the answer, and support conditional requests with ETag so clients that do ask get 304 Not Modified. Add server-side caching for the data itself if the database is still busy, and invalidate it when an administrator changes the list.

How to answer:

Separate client caching, conditional requests, and server caching, and explain invalidation when master data changes.

AHow would you manage master data shared by many schools in a multi-school product?design

Separate global reference data, such as a standard subject catalogue, from school-specific data, such as sections and timetables; scope every school-specific row by school; version changes to shared data; cache per school with clear invalidation; and let administrators change only their own school's data.

How to answer:

Discuss global versus tenant-owned data, isolation, caching keys, change control, and migration of existing schools when the shared catalogue changes. Module 13 builds this.

FWhat is a many-to-many relationship? Give an example from a school system.concept

Each row on one side can relate to many rows on the other, and the other way round. A student has several guardians, and a guardian can have several children at the school. It is stored in a junction table, such as StudentGuardians, with one row per link.

FWhat is a composite key?concept

A primary key made of more than one column. In StudentGuardians it is (StudentId, GuardianId): the pair is unique, so a guardian is linked to the same student only once. In EF Core it is declared with HasKey(sg => new { sg.StudentId, sg.GuardianId }).

FShould an endpoint return 404 or an empty list when a student has no guardians?design

An empty list with 200: the student exists, and the answer to "which guardians?" is "none". Return 404 only when the parent resource, the student, does not exist, so clients can tell the two cases apart.

MHow do you map a junction table that has its own columns in EF Core?coding

As an entity of its own, such as StudentGuardian, with a composite key and two one-to-many relationships, one to each side. EF Core's automatic many-to-many mapping hides the junction table and has no place for columns like Relationship or IsPrimaryContact.

MHow do you enforce 'at most one primary contact per student' in SQL Server?coding

With a filtered unique index on StudentId that includes only rows where IsPrimaryContact = 1. Students may have many guardians, but only one row per student can be in the index, so a second primary contact fails with error 2601.

MHow can one controller serve routes under two different resources?coding

Leave the controller without a class-level route, or ignore it, and start each action's route with "/", which makes it absolute, such as [HttpGet("/api/students/{admissionNumber}/guardians")] and [HttpGet("/api/guardians/{guardianId:int}/students")].

SSome students show two primary contacts after two years of use. How do you fix the system?scenario

Fix the code so setting a new primary clears the old one in the same save; clean existing data with a script that keeps one primary per student by an agreed rule and reviews unclear cases; then add a filtered unique index so the data can never break the rule again, whatever code or tool writes to it.

How to answer:

Cover the code fix, the data repair with its decision rule and verification, and the database constraint as the lasting guard.

SWhich personal details should a list endpoint return, and how do you decide?design

Only what the screens using it need: a staff list needs names, codes, and work emails, not personal phones or dates of birth. Put more sensitive details on single-resource endpoints that fewer roles may call, and check every DTO against who will see it.

How to answer:

Mention data minimisation, roles and authorization (Module 12), logging and caching risks of personal data, and reviewing DTOs as part of design.

AHow would you model people who play several roles, such as a teacher who is also a parent at the school?design

Separate the person from their roles: one person record with shared identity and contact details, and role records such as Teacher and Guardian that reference it, each with role-specific data and permissions. Logins attach to the person, and authorization checks roles, so one sign-in can see both the staff and the parent views.

How to answer:

Compare per-role tables (as in the SMS today) with a person-plus-roles model, discuss duplication, identity, and authorization, and how you would migrate.

FWhat is a race condition in a web API? Give an example.concept

Two requests run at the same time and the result depends on their timing. Two clerks enrolling into one section both read "highest roll number 0" and both save roll number 1; one of them acted on information that was no longer true.

FWhy put the enrollment rules in a service rather than in the controller?design

The rules (active student, not already enrolled, capacity, next roll number) are business logic that must hold for every caller, and they need several repository calls in one transaction. A service keeps them in one tested place; the controller only translates HTTP to the service call.

FWhich status codes fit 'section is full', 'student not found', and 'student not active'?concept

Section full: 409 Conflict, because the request clashes with the section's current state. Student not found: 404. Student not active: 422, a business rule. Each also carries an SMS error number, such as 50034, 50030, and 50032.

MHow do you make 'check, then insert' safe when two requests act on the same group of rows?coding

Serialize them on something that represents the group: start a transaction and lock its row, such as SELECT ... FROM Sections WITH (UPDLOCK, ROWLOCK), then check and insert, then commit. Requests for the same section wait; other sections are unaffected. Keep a unique constraint as a final guard.

MHow do you generate the next number within a group, such as a roll number per section?coding

While the group is locked, read the highest existing number and add one, then insert, all in one transaction; back it with a unique constraint on (group, number). Without the lock, two requests compute the same number. A sequence or identity does not fit, because numbering restarts per group.

MWhy might a soft-delete query filter cause duplicate numbers, and how do you avoid it?concept

Rows hidden by the filter still exist and still hold their numbers in the unique constraint. If the highest number is read through the filter, a removed student's number can be handed out again and the insert fails. Read the highest number with IgnoreQueryFilters, while counting capacity with the filter.

SHow do you test that a lock really serializes concurrent requests?design

Make the timing deterministic: in the test, take the lock with one connection and hold it, start the operation on a second connection, check that it has not finished after a delay, release the lock, and check the operation then completes correctly. Sending two requests by hand rarely overlaps reliably.

How to answer:

Explain why naive parallel tests are flaky, describe the hold-the-lock pattern, and mention cleaning up test data when the code under test runs its own transaction.

SWhen would you choose pessimistic locking over optimistic concurrency?design

When conflicts are likely and the work under the lock is short, such as many clerks enrolling into the same sections in admission week: waiting briefly is better than failing and retrying. Choose optimistic concurrency when conflicts are rare or when a user thinks between reading and saving, where holding a lock would block others for minutes.

How to answer:

Compare conflict rate, lock duration, user experience, and deadlock risk, with an example of each from the SMS (enrollment versus fee payment screens).

AAdmission week overloads one popular section with waiting enrollments. How would you scale the design?design

Keep the lock scope minimal and the locked work short; move slow work (notifications, documents) after the commit or to a background queue; consider assigning roll numbers in a later batch step so admission only reserves a place; and use a queue per section if demand truly exceeds what one lock can serve.

How to answer:

Identify the contention point, reduce work inside it, separate reservation from numbering, and discuss asynchronous processing and its effect on the user experience.

FWhy take a whole section's attendance in one request instead of one request per student?design

One request is faster on weak networks, and it can be saved in one transaction, so a register is never half saved. It also lets the API check the register as a whole, such as that every enrolled student is included exactly once.

FWhat does it mean that the attendance PUT is idempotent, and why does it matter?concept

Sending the same register twice leaves the same result as sending it once: the second request created and updated nothing. On school Wi-Fi, apps retry timed-out requests, so retries must be harmless instead of creating duplicate records.

FHow is the attendance percentage calculated in the SMS?concept

(Present + Late) divided by all recorded days, times 100, the same rule as Lesson 18's SQL. Kabir had 2 present days out of 3 recorded in July, which is 66.67%.

MWhat is TimeProvider, and why use it instead of DateTime.Now?coding

.NET's built-in abstraction for the current time. The app registers TimeProvider.System; tests pass a provider stopped at a fixed moment. Rules such as "no future dates" then give the same result on every test run, instead of changing as real days pass.

MHow do you implement 'update if it exists, otherwise insert' for a batch with EF Core?coding

Load the existing rows for the batch's key (section and date) as tracked entities, then for each item update the matching entity if its values differ, or add a new one. One SaveChangesAsync writes the updates and inserts in one transaction, with a unique constraint as the final guard against duplicates.

MWhy should attendance reports be aggregated in SQL rather than in C#?concept

A day has about 10,000 records. GROUP BY in SQL Server sends back ten rows of counts; loading the records into the API to count them would move all 10,000 rows for the same ten numbers. With an index on the date, the SMS's daily summary took about 120 ms over 600,000 rows.

SReports show some students above 100% attendance. What likely happened, and how do you prevent it?scenario

Duplicate records for the same student and day, usually from retried requests that inserted again. Repair the duplicates, add a unique constraint on (enrollment, date) if missing, and make the save idempotent: one request per register, updating existing records instead of inserting blindly.

How to answer:

Work from symptom to cause (duplicates), name the missing guards (constraint, idempotency), and cover the data repair with verification.

SShould the attendance endpoint accept a partial register? Discuss the trade-off.design

Requiring the complete register prevents a forgotten student from looking present or unrecorded, and keeps every day's data comparable. Accepting partial registers suits workflows such as marking late arrivals later; then the API needs explicit "not marked" handling in reports. The SMS requires complete registers and allows corrections by sending the register again.

How to answer:

Weigh data quality against flexibility, describe what reports must do in each design, and say how corrections work.

AAttendance grows by 10,000 rows a day across many schools. How would you keep it fast and manageable for years?design

Index for the main access paths (date; enrollment and date), keep reports aggregated in SQL, pre-compute daily and monthly summaries in a summary table updated after each register, archive or partition old years by date, and serve dashboards from the summaries instead of the raw rows.

How to answer:

Estimate the growth, then cover indexing, summary tables, partitioning (SQL Extras), archiving, and how reports stay correct when summaries are updated.

FHow would you design REST routes for entering exam marks in a school system?design

Give each paper (one subject's exam for one class) its own address and treat a section's marks sheet as one resource: GET and PUT /api/exam-papers/{paperId}/marks?sectionId=19. Exams and their papers are read with GET /api/exams and /api/exams/{examId}/papers?classId=10, and a report card with GET /api/students/{admissionNumber}/report-cards/{examId}.

FWhy should an absent student not simply get 0 marks?concept

Absent and a score of 0 mean different things, and reports must show the difference. The SMS stores IsAbsent = true with null marks; the report card shows "Absent", and a line must have marks or absent, never both (error 50053).

FWhen does the SMS report card show a percentage and a final result?concept

Only when every paper of the exam has been entered. Until then the result is "Incomplete" and the percentage is null, because a missing paper would make the percentage look higher. A complete card is "Pass" only if every paper reached its pass marks.

MWhen should a validation check move into a shared class?design

When a second feature needs exactly the same rule. In the SMS, the register check (every student once, nobody else) was written for attendance; marks sheets needed it too, so it moved to RegisterCheck, and both services call it. Sharing earlier, with only one user, often guesses the wrong shape.

MWhy keep report card rules in a service instead of in the SQL query?design

The query only returns what is stored: each paper and the student's mark if there is one. The service decides Pass, Fail, Absent, grades, and the result. Rules change between schools and boards, and in C# they can be unit tested without a database, as the SMS report card tests do.

MA database trigger raises THROW 50001 for invalid marks. How should the API handle it?coding

Catch the SqlException with Number 50001 in the repository and throw the same SchoolRuleException 50001 that the service raises for the same rule. The exception handler then answers 422 with errorCode 50001, whether the C# check or the database caught the problem. Without this, the client gets a 500.

SPrinted report cards showed percentages that were too high for some students. How do you investigate and prevent it?scenario

Compare a wrong card with its marks: the usual cause is a percentage calculated from the papers entered so far while some papers were still missing. Fix the rule (no percentage, result "Incomplete", until every paper is entered), add tests for incomplete cards, and give the office a list of missing papers before printing. Reprint the affected cards.

How to answer:

Reproduce with real data, name the rule that was wrong, fix it with a test, and add a process check so incomplete data cannot reach print again.

SShould the 'marks within the maximum' rule live in the API, the database, or both?design

Both. The API checks first and gives a clear message for the user. The database trigger is the final guard for every program that writes marks, such as imports or scripts. Both use error number 50001, and the repository translates the database's error, so clients see one consistent error.

How to answer:

Explain defence in depth, who writes to the database besides the API, and how to keep both checks consistent for clients.

AEach school in a group uses different grade scales and pass rules. How would you design the report card logic?design

Keep the data query the same and make the rules configurable per school: grade scales as data or as strategies (the IGradeScale idea from Lesson 56), pass marks per paper, and result rules per board. Version the rules so old report cards can be reproduced exactly, cache them per school, and cover each school's rules with tests built from real past results.

How to answer:

Separate stored data from rules, show how rules vary per school, and cover versioning, reproducibility, and testing.

FWhat is set-based SQL, and why use it to create invoices for a whole class?concept

Set-based SQL handles many rows in one statement, such as INSERT ... SELECT, instead of one statement per row in a loop. The SMS bills a class of 1,000 students with two inserts and a summary in one transaction and one round trip, in about 0.3 seconds, instead of about 4,000 separate statements.

FWhat is a SQL Server sequence, and why use one for invoice numbers?concept

A sequence is a database object that hands out the next number each time NEXT VALUE FOR is called, safely across many users at once. MAX(number) + 1 can give two requests the same number; a sequence never does. The SMS formats the value as INV-2026-NNNNNN.

FWhy are there gaps in invoice numbers, and is that a problem?concept

A sequence never takes a number back, even when the transaction that used it rolls back or the row is later deleted. In the SMS, test runs used 2,000 numbers, so the next real invoice was INV-2026-002013. Gaps are normal; what must never happen is a duplicate, which the unique constraint on InvoiceNumber prevents.

MHow do you make a batch endpoint, such as 'bill this class', safe to run twice?design

Let the batch skip what is already done and report it. The SMS insert uses NOT EXISTS to skip students who already have an active invoice; the second run reported 0 created and 1,006 already invoiced. A unique index (one active invoice per enrollment) is the final guard.

MHow do you add an item row for each new invoice created by an INSERT ... SELECT?coding

Capture the new rows with OUTPUT INSERTED.Id INTO a table variable, then insert the items with INSERT ... SELECT from that table variable joined to the fee lines (a CROSS JOIN, since every invoice gets every line). This works because FeeInvoices has no trigger; on a table with triggers, OUTPUT must use INTO, as here.

MHow do you build a paged report that also shows totals for everything, in one round trip?coding

Send two statements with the same FROM and WHERE: one returns COUNT and SUM over the whole filter, the other returns one page with ORDER BY and OFFSET/FETCH. Read both with Dapper's QueryMultiple. Totals computed from the page alone would change with the page size.

SA server restart halfway through billing left half a class with invoices; a retry then billed the first half twice. How do you fix it?scenario

Repair first: find enrollments with two active invoices and cancel the duplicates, with an audit note. Then fix the design: bill the class in one set-based transaction, so a failure leaves nothing half-done; skip students already billed, so a retry is harmless; and add a filtered unique index so the database refuses a second active invoice.

How to answer:

Separate the data repair from the design fix, and explain how atomicity, idempotency, and a database constraint each prevent a part of the problem.

STwo clerks click 'Generate invoices' for the same class at the same moment. What happens in your design?scenario

Each run first takes an application lock for the class (sp_getapplock), so the second clerk waits until the first commits, then its NOT EXISTS check finds every student already billed and creates nothing. If anything slipped past, the filtered unique index would refuse the duplicate and the API would answer 409 (50017). The first SMS version used UPDLOCK, HOLDLOCK on the check instead, and under load two runs could deadlock (error 1205); the application lock removed that.

How to answer:

Walk through both transactions step by step, name the lock and the constraint, and say what the second clerk sees.

ABilling must run for 1,000 schools at the start of each term. How would you design it?design

Run billing as background jobs per school and class, not inside web requests. Each job is set-based, one transaction, and idempotent, so failed jobs can simply be retried. Record each run (who, when, counts) for audit, spread the load over time, give each school its own number series, and notify the office when its run is done. Monitor failures and totals per school.

How to answer:

Cover moving work off the request path, idempotent retries, data partitioning per school, numbering, auditing, and monitoring.

FWhy build a dashboard endpoint instead of letting the screen call the existing endpoints?design

One request is quicker than six, especially on phones and slow networks, and it is less work for the server. The endpoint is shaped by the screen, not by the tables. The SMS keeps the detailed endpoints for their own screens and adds GET /api/dashboard/summary for the first screen.

FWhat does Dapper's QueryMultiple do, and what must you be careful about?coding

It sends several SQL statements in one round trip and returns a reader for their results. You read each result in the same order as the statements; reading out of order maps the wrong rows. The SMS dashboard reads five results this way.

FWhat is a covering index?concept

An index that holds every column a query needs, so SQL Server reads only the index and never the table. INCLUDE adds columns to the index without making them part of the key. In the SMS, adding EnrollmentId to the attendance date index cut one day's count from 1,606 pages read to 44.

MHow do you find which statement in a SQL batch is slow?coding

Run it with SET STATISTICS TIME ON to get the CPU and elapsed time of each statement, and SET STATISTICS IO ON to see how many pages each one reads from each table. The SMS dashboard's attendance statement took 126 ms and read 1,606 pages, which pointed straight at a missing index column.

MAn index includes Status, yet a query on that table still reads the table. Why?scenario

The query needs another column the index does not hold. In the SMS, the dashboard joins each attendance record to its enrollment, so it needs EnrollmentId as well as Status. Rebuilding the index with INCLUDE (EnrollmentId, Status) and DROP_EXISTING = ON made it cover the query.

MWhat does [ResponseCache(Duration = 60)] do on an ASP.NET Core action?concept

It adds the header Cache-Control: public,max-age=60, so browsers and proxies may reuse the response for a minute. It does not cache anything on the server by itself. It suits numbers such as a dashboard that may safely be a little old.

SYou added an index to speed up a query, but the timings did not change at all. What do you check?scenario

Check that the change was really made: in the SMS, the script's re-run check looked for a column that was already included, so it skipped the rebuild. Then read the index definition from sys.index_columns, and compare pages read with STATISTICS IO before and after. Only trust a fix once the numbers move.

How to answer:

Start from verifying the change itself, then measure with the right tools, and explain how you would prevent a silent no-op in future scripts.

SA dashboard test fails sometimes when the whole suite runs, but never alone. What is likely wrong?scenario

It depends on data that other tests change at the same time: test classes run in parallel. In the SMS, fee totals change while FeeBillingTests creates invoices, so the dashboard test checks only numbers that no other test changes. Alternatives are separate test data, a collection that runs tests one after another, or a database per test run.

How to answer:

Explain parallel test execution, shared data, and the options to isolate tests, with their costs.

AThe dashboard is opened by thousands of users across many schools. How would you keep it fast?design

Keep one round trip per dashboard and covering indexes for its queries. Cache the result per school for a short time on the server (memory or a distributed cache), refreshed in the background. Pre-compute heavy numbers such as daily attendance into summary tables. Send Cache-Control so clients reuse answers, and watch query times per school in monitoring.

How to answer:

Layer the answer: query efficiency, server-side caching with clear freshness rules, pre-computation, and measurement in production.

Data access in the API

FHow can you switch an API's data access from EF Core to Dapper without changing the controllers?concept

Keep data access behind interfaces such as IStudentRepository, and let one registration method decide the classes. Controllers and services only ask for the interfaces. In the SMS, AddSchoolData changed from the EfCore classes to the Dapper classes, and no controller changed.

FEF Core had a soft-delete query filter. What must you do instead when you use Dapper?concept

Write the condition yourself, such as IsDeleted = 0, in every query that reads the table, including joins and counts. Dapper runs exactly the SQL you write. A test with one removed student catches a forgotten condition.

FWhy might a team choose Dapper for an API instead of EF Core?concept

Dapper runs SQL that the team writes and can read, so queries are exact and easy to review with a database team, and its overhead is very small. EF Core gives change tracking, LINQ, migrations, and less code for simple writes. Many teams use EF Core for writes and Dapper for heavy reads; the SMS chose Dapper for the whole API.

MDapper threw SqlException 547 when saving an attendance status. What went wrong?scenario

The enum AttendanceStatus was passed as it is, and Dapper sends an enum's number (Late is 2). The Status column holds names, and CK_AttendanceRecords_Status refused the number. Pass Status.ToString(). EF Core did this conversion for us with HasConversion<string>().

MHow do you save several related changes together with Dapper?coding

Open the connection, start a SqlTransaction, pass the transaction to every Dapper call, and commit at the end. If anything throws, disposing the transaction without committing rolls everything back. In the SMS, the invoice update and the new payment, and the attendance updates and inserts, each use one transaction.

MHow do you implement optimistic concurrency with a RowVersion column in Dapper?coding

Read the RowVersion with the row. Update with WHERE Id = @Id AND RowVersion = @RowVersion, and read the new value with OUTPUT INSERTED.RowVersion. If no row comes back, someone else saved first: roll back and report a conflict. The SMS reports it as error 50014, just as the EF Core version did.

SAfter switching to Dapper, a payment is saved but the API answers 500 with a NullReferenceException. How do you find and fix it?scenario

Use the traceId to find the log entry and its stack trace. In the SMS it pointed to the mapping code, which read payment.FeeInvoice. EF Core's relationship fix-up had always filled that link; Dapper does not. The right fix is in the entity: RecordPayment sets FeeInvoice = this, so the object model is correct whichever tool loads it. Then add a test that checks the link.

How to answer:

Go from symptom to log to cause, explain the hidden ORM behaviour, and say why the fix belongs in the domain model rather than the repository, with a test to keep it fixed.

SHow would you prove that replacing a data-access layer did not change the API's behaviour?design

Run the same tests against both implementations (the SMS enrollment tests run once per tool, including the lock test). Call the same requests on the old and new builds and diff the responses; the SMS compared 20 GET answers and found no difference. Exercise every write path, then compare timings. Keep the old implementation until all of this passes.

How to answer:

Cover automated tests, side-by-side comparison of real responses, write paths, performance, and a safe rollout with the old code still available.

AYour company's APIs use EF Core, and one team wants Dapper. How would you set a data-access standard across many teams?design

Agree what must be true whatever the tool: repositories behind interfaces, one transaction per business change, concurrency checks, soft-delete rules, parameterised SQL, and integration tests against a real database. Allow EF Core for most CRUD and Dapper where SQL control or speed matters, decided per service and recorded. Provide shared helpers (connection factory, transaction helper, row-to-DTO patterns) and review checklists for the things EF Core did implicitly. Measure before switching for speed.

How to answer:

Separate the non-negotiable rules from the tool choice, give criteria for choosing, and explain how you support teams and enforce the rules.

Filters

FWhat is a filter in ASP.NET Core MVC?concept

Code that runs before and after controller actions, inside MVC, for jobs many actions share. Filters can read the action, its attributes, and its bound arguments, and can answer the request themselves. The SMS uses a filter for read-only mode and another for checking date ranges.

FIn what order do the filter types run?concept

Authorization filters, then resource filters, then model binding and validation, then action filters around the action, then exception filters if it throws, then result filters around writing the result. Resource filters also run again at the very end, on the way back.

FWhen would you use middleware instead of a filter?concept

When the job applies to every request, whatever happens next, including requests for files or unknown routes, which never reach a filter. Use a filter when the job depends on which action runs or on its bound arguments. In the SMS, request timing is middleware; read-only mode and date checks are filters.

MHow does a filter stop a request from reaching the action?coding

It sets context.Result (or, in an async filter, does not call next). That result becomes the response, and the action and the later filters never run. The SMS's ReadOnlyModeFilter sets a 503 ApiResponse this way.

MWhy might a filter answer 503 to a request whose body is invalid, instead of 400?scenario

It is a resource filter, which runs before model binding and validation. In the SMS read-only mode, an empty admission request got 503 because the filter refused it before validation ever read the body. An action filter would run after validation, and the client would get 400 first.

MAn attribute filter needs a service from dependency injection. How do you supply it?coding

Attribute filters are created by .NET, not by dependency injection, so their constructors cannot ask for services. Use [ServiceFilter(typeof(MyFilter))] (the filter is registered and taken from DI) or [TypeFilter(typeof(MyFilter))] (created with services filled in), or register the filter globally with options.Filters.Add of the type, as the SMS does for ReadOnlyModeFilter.

SThe school must stop all changes for two days at year end, but parents must still read report cards. How do you build it?design

A global resource filter that refuses every non-GET request with 503 and Retry-After while a setting is on, with an attribute to exempt actions such as sign-in. Read the setting with IOptionsMonitor, so the office can switch it without a restart or deployment. Keep the message clear, and test both modes.

How to answer:

Choose the mechanism (a resource filter), explain why it runs before binding, how the switch changes at run time, which actions are exempt, and what status and headers clients get.

SYou changed a setting in appsettings.json while the API was running, but a filter still uses the old value. Why?scenario

The filter reads the setting through IOptions, which binds the value once. IOptionsMonitor.CurrentValue (or IOptionsSnapshot per request) sees reloaded configuration. Also check the file is the one the app actually reads (the content root) and that reloading is on, which is the default for appsettings.json.

How to answer:

Name the three options interfaces and when each sees changes, and how you would verify the reload.

APayments are sometimes recorded twice when a phone app retries after a timeout. How would you design idempotency for the API?design

Clients send an Idempotency-Key header with each payment. A resource filter (or middleware) stores the key with the response in a shared store (database or distributed cache) for a limited time, and when the same key arrives again it replays the stored response instead of running the action. Store keys per user, handle two identical requests arriving at once with a unique constraint or lock, and reject a reused key with a different body.

How to answer:

Cover the client contract, where keys and responses are stored, concurrent duplicates, expiry, and how it works across several servers.

Logging

FWhat are log levels, and when would you use Warning instead of Error?concept

Levels rank how important an entry is: Trace, Debug, Information, Warning, Error, Critical. Warning is for something unusual that was handled, such as a school rule refusing a request or a slow request; Error is for a failure the user saw, such as an unhandled exception. Settings choose the minimum level per category.

FWhat is structured logging?concept

Writing log entries from a message template with named holes, such as "Payment {ReceiptNumber} recorded", so each value is kept as a separate property. Log systems can then search and count by property (ReceiptNumber = RCP-2026-000069) instead of parsing text.

FWhat should never be written to logs?concept

Passwords, access tokens, signing keys, and personal data such as names, birthdays, phone numbers, and addresses, and whole request or response bodies that may contain them. Logs are read by more people and kept in more places than the database. The SMS logs ids only.

MWhy is logger.LogInformation($"Payment {receipt}") a bad habit?coding

String interpolation turns the value into plain text, so it cannot be searched as a property, and the string is built even when the level is turned off. Use a message template, LogInformation("Payment {ReceiptNumber}", receipt), or a [LoggerMessage] method.

MWhat does the [LoggerMessage] attribute give you?coding

The compiler generates the body of a static partial logging method: fast (no boxing, the template parsed once), typed (a missing argument is a build error), with a fixed event id and level. The SMS keeps every deliberate message in one SchoolLog class this way.

MHow do you add the current user to every log entry of a request?coding

Open a logging scope after authentication, for example in a small middleware: logger.BeginScope("UserId:{UserId}", userId). Every entry written inside the scope carries UserId, and the JSON formatter stores it as a property. Code that runs outside the scope, such as the exception handler, must add the user to its own message.

SA parent sends a screenshot of an error with a trace id. How do you find what happened?scenario

Search the logs for the trace id. In ASP.NET Core it is the middle part of the response's traceId (00-<TraceId>-<SpanId>-00), and every log entry of that request carries it as a scope. The matching entries show the request path, the user, the rule or exception, and the timing.

How to answer:

Explain how the trace id links the response to the logs, what the entries contain, and why logs must include scopes and be searchable for this to work.

SThe team finds parents' phone numbers and passwords in the API logs. What do you do?scenario

Stop the leak first: remove request-body logging and any log line that includes personal data, and deploy. Then treat the stored logs as an incident: restrict access, delete or redact them according to policy, and ask affected users to change passwords. Prevent it returning with deliberate log messages that take ids only, and tests that check sensitive text never appears in logs.

How to answer:

Order the response: contain, clean up existing data, notify, then prevent with design and tests.

AHow would you design observability for an API that runs on many servers for many schools?design

Structured JSON logs with fixed event ids, sent to a central store; distributed traces with the same trace ids across services (OpenTelemetry); and metrics such as request rates, error rates, and response times per endpoint and school. Add the school and user ids as scopes, alert on symptoms (error rate, slow requests), keep personal data out, and set retention and access rules for each kind of data.

How to answer:

Cover the three signals (logs, traces, metrics), how they are linked, what you alert on, and the privacy and cost limits.

Caching

FWhat is a cache, and what data is worth caching?concept

A cache keeps a copy of an answer close by so the next request does not ask the source again. Cache data that is read far more often than it changes and that may safely be a little old, such as the current academic year or the list of subjects. Never cache data that must be exact, such as a fee balance.

FWhat is the difference between [ResponseCache] and a server-side cache?concept

[ResponseCache] sends a Cache-Control header so each browser or proxy may keep its own copy; the server cannot take it back early. A server-side cache such as HybridCache keeps the copy in the API's memory, serves every client from it, and can remove entries when data changes. They work well together.

FWhat makes a good cache key?concept

It names everything the answer depends on, and nothing else, so two different questions never share an answer. The SMS dashboard key is dashboard:{yearId}:{date}; leaving out the date would return one day's numbers for another. Per-user answers need the user in the key, or should not be cached.

MHow does HybridCache.GetOrCreateAsync behave, and what is stampede protection?concept

It returns the cached value for a key, or runs the given function once, stores its result, and returns it. Stampede protection means that when many requests ask for the same missing key at once, the function runs only once and all of them share the result, instead of all hitting the database together.

MHow do you add caching without changing the code that uses a repository?design

Write a decorator: a class that implements the same interface, holds the real repository, answers reads from the cache, and passes everything else through. Register it in place of the real one. In the SMS, CachedMasterDataRepository wraps the Dapper repository, and no controller or service changed.

MHow do you remove cached answers when the data changes?coding

Give related entries a tag when you store them, and remove the tag in the same code path that changes the data. In the SMS, every subject entry carries the tag "subjects", and AddSubjectAsync calls RemoveByTagAsync("subjects"), so the new subject appears at once instead of after an hour.

SParents see an old fee balance in the app after paying. What went wrong, and what do you change?scenario

The balance was cached, so the app showed the copy from before the payment. Money and other exact, per-person data should not be cached; if a cache is truly needed, remove the student's entry in the payment code path and keep expiry very short. Review every cached item with the question: what harm does the old version cause?

How to answer:

Identify the stale cache as the cause, decide whether the data should be cached at all, and describe invalidation and review rules.

SThe API runs on three servers with in-memory caches. A subject is added on one of them. What happens?scenario

Only that server removes its cached subjects; the other two keep their copies until they expire, so users may see different lists for up to an hour. Options: shorter expiry, a shared distributed cache (such as Redis as HybridCache's second level), or broadcasting removals to every server.

How to answer:

Explain per-server memory caches, the visible effect, and compare the fixes by freshness, cost, and complexity.

AHow would you design caching for an API that serves 1,000 schools?design

Put the school in every key (and tag by school), so no school ever sees another's data. Use a two-level cache: memory on each server for speed, plus a shared distributed cache for consistency and warm restarts. Cache master data and computed dashboards with expiry matched to how often each changes, remove tags in the code that changes data, protect against stampedes, and watch hit rates and memory per school.

How to answer:

Cover isolation between tenants, the cache levels, what is cached and for how long, invalidation, and monitoring.

Versioning

FWhat is a breaking change in an API? Give examples.concept

A change that makes existing clients fail or misread data: removing or renaming a response field, changing a field's type or meaning, making an optional request field required, or changing a status code. Adding a field, an endpoint, or an optional request field is not breaking, because old clients ignore it.

FWhat are the common ways to put a version in an API request?concept

In the URL path (/api/v2/students/...), in a header (X-Api-Version: 2), or in the query string (?api-version=2.0). URL versions are visible and easy to test and cache; headers keep URLs clean but are invisible in links and logs. The SMS uses the URL segment, and the key is to use one style everywhere.

FHow do existing apps keep working when you add versioning to an API that had none?concept

Make unversioned requests mean version 1. In Asp.Versioning, set DefaultApiVersion to 1.0 and AssumeDefaultVersionWhenUnspecified to true. In the SMS, /api/students/... still answers exactly as before, and /api/v1/... is the same endpoint with the version named.

MHow do you serve two versions of the same endpoint in ASP.NET Core controllers?coding

Add Asp.Versioning.Mvc, mark the existing controller [ApiVersion("1.0")], and add a new controller marked [ApiVersion("2.0")] with a route such as api/v{version:apiVersion}/students. Give both the same [ControllerName] so the package groups them and reports both versions.

MWhy might api-supported-versions show only one version on each of two versioned controllers?scenario

Asp.Versioning groups versions by controller name. A StudentsController (1.0) and a StudentsV2Controller (2.0) look like two different APIs, so each reports only its own version. [ControllerName("Students")] on the version 2 class makes both report 1.0, 2.0.

MWhen should you add a new API version instead of changing the existing one?design

Only for breaking changes. If the change can be additive, such as adding firstName and lastName next to fullName, do that: old clients keep working and there is one version to maintain. Add a version when a field must be removed, renamed, or change meaning, or a response must be reshaped.

SA field was renamed in the API and every installed mobile app now shows blank names. What do you do?scenario

Restore the old field at once (or serve the old shape again) so installed apps work. Move the rename into a new version that new app releases use. Add a rule and a review step: no field is removed or renamed without a new version and a deprecation date, and add tests that pin the version 1 response shape.

How to answer:

Put users first (restore), then do the change properly (versioning), then prevent it (rules and contract tests).

SHow do you retire an old API version safely?design

Mark it deprecated (so responses list it in api-deprecated-versions) and publish a date; log which version each request uses and contact the clients still on it; after the date, remove it and answer its routes with a clear error. For a school, one full academic year is a sensible notice period.

How to answer:

Cover announcing, measuring usage, communicating, and the final removal, with a realistic timeline.

AYour platform has many APIs used by internal and partner apps. How would you set a versioning policy?design

One style for all APIs, semantic rules for what counts as breaking, and a preference for additive changes. Breaking changes get a new major version with a published support period (for example, at least 12 months), deprecation headers, per-version documentation, and usage dashboards per client. Contract tests guard each supported version, and an API gateway can route versions to different services if needed.

How to answer:

Cover the style, the definition of breaking, support periods, communication, documentation, enforcement with tests, and how clients are tracked.

Background jobs

FWhat is a hosted service in ASP.NET Core, and what is BackgroundService?concept

A hosted service is a class the app starts when it starts and stops when it stops (IHostedService, registered with AddHostedService). BackgroundService is a base class for one: you override ExecuteAsync, which runs in the background for the life of the app, and its stoppingToken is cancelled at shutdown.

FWhich work should move out of a request into the background?concept

Work the user's next step does not depend on, especially slow work or work that calls another service: sending messages, emails, and reports. In the SMS, saving a payment stays in the request; the receipt message is queued. Moving it also stops a slow or failing provider from failing the payment itself.

MHow do you pass work from a controller to a background worker in ASP.NET Core?coding

Register a queue as a singleton, for example a bounded Channel of messages. The controller writes a message and returns at once; a BackgroundService reads the channel with ReadAllAsync and processes each message. Bounded with FullMode.Wait means a flood of work waits for room instead of using up memory.

MYour BackgroundService needs a scoped repository. How do you use it?coding

Not through the constructor: a hosted service is a singleton, and the app refuses to start with "Cannot consume scoped service ... from singleton IHostedService". Inject IServiceScopeFactory, create a scope for each piece of work (CreateAsyncScope), and resolve the repository from that scope; disposing the scope cleans it up.

MWhat happens if ExecuteAsync throws an unhandled exception, and how do you guard against it?scenario

Since .NET 6 the default BackgroundServiceExceptionBehavior is StopHost: the whole app shuts down, every endpoint included. Catch exceptions inside the loop (except cancellation at shutdown), log them, and carry on with the next message or the next scheduled run.

MHow would you write and test a job that must run every day at 18:00?coding

A BackgroundService loop: get the time from TimeProvider, work out the next 18:00, await Task.Delay(next - now, timeProvider, stoppingToken), run, repeat. Because the clock is injected, a test uses FakeTimeProvider: set it to 17:59, start the job, Advance one minute, and check the job ran, without waiting.

SThe API runs on two servers and both run the evening reminder job. How do you stop duplicate reminders?scenario

Let the database decide. Record each reminder in a table with a unique key on (invoice, date) before sending, and send only if the insert succeeded; the second server gets a duplicate-key error and skips that invoice. Alternatives are a distributed lock (such as sp_getapplock) or a scheduler that runs each job on one server.

How to answer:

Name the problem (every instance runs every hosted service), then give an idempotent design and say why it needs no coordination between servers.

SWhy is an in-memory queue risky, and what is the outbox pattern?design

Messages waiting in memory are lost when the app stops or crashes. With an outbox, the message is saved in a table in the same transaction as the business change (such as the payment); a worker reads unsent rows, sends them, and marks them sent. Nothing is lost on restart, but sending is at least once, so receivers must handle duplicates.

How to answer:

Explain what is lost and when, describe the outbox steps, and mention the at-least-once trade-off.

AHow would you design background processing for a school platform that sends millions of messages a day?design

Separate the API from the workers: the API writes messages to an outbox table or a durable broker (Azure Service Bus, RabbitMQ), and a scalable pool of worker services sends them. Add retries with backoff, a dead-letter queue for messages that keep failing, idempotency keys so retries never double-send, rate limits per provider, and dashboards for queue length and failures. Schedules run in one place (Hangfire, Quartz.NET, or a cloud scheduler) so each job runs once.

How to answer:

Cover durability, scaling the workers, retries and dead letters, idempotency, scheduling, and monitoring.

FWhen should an endpoint answer 202 Accepted instead of 200 OK?concept

When it has accepted the work but not finished it, because the work continues in the background. 200 says "done, here is the result"; 202 says "accepted, it will be done". In the SMS, POST /api/fee-reminders answers 202 with how many reminders were queued; the worker sends them afterwards.

Health checks

FWhat is a health check endpoint, and who calls it?concept

An address, such as /health/ready, where the API reports whether it is working. Load balancers call it every few seconds to decide which servers get traffic, container platforms use it to restart or pause instances, and monitoring tools use it to alert the team.

FWhat is the difference between a liveness check and a readiness check?concept

Liveness asks "is the process running?" and failing it usually means restart the process. Readiness asks "can it do its work now?" (database reachable, workers running) and failing it means send no traffic until it recovers. A database problem belongs in readiness, because restarting the API does not fix the database.

FWhat do Healthy, Degraded, and Unhealthy mean, and which HTTP codes do they return?concept

Healthy: everything works (200). Degraded: it works but needs attention, such as a growing queue (200, so traffic keeps flowing). Unhealthy: it cannot do its job, such as the database being unreachable (503).

MHow do you write a custom health check for SQL Server in ASP.NET Core?coding

Implement IHealthCheck: open a connection, run SELECT 1, return HealthCheckResult.Healthy; catch exceptions (except cancellation) and return Unhealthy with the exception, so it is logged. Register it with AddHealthChecks().AddCheck("database", tags: ["ready"], timeout: ...) and map it with MapHealthChecks.

MYour health endpoint returns 401 behind the load balancer and every server is marked down. Why, and what do you change?scenario

A fallback authorization policy requires a token on every endpoint, and the load balancer sends none. Mark the health endpoints AllowAnonymous, keep their body free of secrets and exception details, and also exclude them from rate limiting, because a 429 looks just as dead.

MHow can a health check tell that a BackgroundService has stopped?coding

BackgroundService.ExecuteTask is the running ExecuteAsync. Hosted services are singletons, so the check can ask for IEnumerable of IHostedService, find the worker, and report Unhealthy if ExecuteTask is completed while the app is running. Queue length and the last run's result can add Degraded warnings.

SThe database failed over for 30 seconds and every API instance restarted, causing a longer outage. What went wrong?scenario

The database check was in the liveness probe, so the platform restarted every instance, and they were still starting when the database returned. Keep liveness trivial (the process answers) and put the database in readiness, which only removes instances from traffic. Add timeouts so a hanging check fails fast.

How to answer:

Separate the two probe types, explain what each one triggers, and show why restarts cannot fix a dependency.

SShould the readiness check include every external service the API uses?design

No. Include what the instance itself needs and can be fixed per instance, such as its database connection. A shared external service (an SMS provider, a payment gateway) failing would mark every instance unready at once and turn a partial problem into a full outage. Monitor those separately and degrade gracefully.

How to answer:

Classify dependencies as critical per instance versus shared, and explain the blast radius of each choice.

ADesign health checking and monitoring for an API running many instances across regions.design

Per instance: a trivial liveness probe and a readiness probe with fast, time-limited checks of its own dependencies, answering only a status publicly and details on an internal address. Per service: synthetic checks from outside that exercise real flows, dashboards of error rates and latency, and alerts with clear owners. Health results can also be pushed (IHealthCheckPublisher) to the monitoring system, and shared dependencies are watched centrally rather than in every probe.

How to answer:

Cover probe design, timeouts, security of details, external synthetic checks, metrics and alerting, and shared-dependency handling.

Testing the API

FWhat is the difference between unit tests, integration tests, and API tests?concept

Unit tests check one class with fakes instead of a database, and run in milliseconds. Integration tests check code together with a real dependency, such as SQL that runs against SchoolDb. API tests run the whole application in memory (WebApplicationFactory) and send real HTTP requests through routing, security, validation, and the database.

FWhat is the test pyramid?concept

A guideline for the shape of a test suite: many fast unit tests at the bottom, fewer integration tests in the middle, and fewer still slow end-to-end or API tests at the top. Fast tests give quick feedback and pinpoint failures; the slower ones prove the parts work together.

FWhat does code coverage measure, and what does it not tell you?concept

The share of code lines (or branches) that ran during the tests. It does not say the lines were checked: a test without asserts still covers code. Use it to find code no test touches, not as proof of quality.

MHow can a test catch a missing dependency injection registration for any controller?coding

Find every controller type in the API assembly and create each one in a DI scope with ActivatorUtilities.CreateInstance, the way MVC does. Collect the exceptions and fail with their messages. It catches the mistake even though the app starts normally, because controllers are only created when a request reaches them.

MHow would you test that no endpoint is accidentally open to anonymous users?coding

Read the endpoints from EndpointDataSource in a WebApplicationFactory, select those with IAllowAnonymous metadata, and compare them with an approved list in the test. With a fallback policy that requires sign-in, every other endpoint is locked; a newly opened one fails the test until someone approves it.

MYour coverage jumped from 60% to 77% after a settings change, with no new tests. What do you check?scenario

The number of lines counted. Excluding CompilerGeneratedAttribute, for example, removes every async method's generated state machine, so most async code disappears from the report. Exclude only truly generated files (such as obj/), and treat any change in coverage without a change in tests as suspicious.

SWhat is approval testing, and how can it protect a public API?design

The test produces output (here, the sorted list of routes with versions) and compares it with an approved file in source control. Any difference fails the test and writes a received file; if the change is intended, the developer replaces the approved file and the change appears in code review. It stops routes being removed or renamed by accident, which would break installed clients.

How to answer:

Define the technique, give a concrete use, and explain how it turns accidental changes into reviewed ones.

SAPI tests share one real database. How do you keep them reliable?design

Each test creates its own data and removes it in finally, or works on data no other test changes; tests that touch the same rows share an xUnit collection so they never run at the same time. Avoid depending on today's date (inject TimeProvider) and on counts that other tests change. Alternatives are a transaction rolled back per test, a tool that resets tables (such as Respawn), or a fresh database container per run.

How to answer:

Cover isolation, cleanup, parallel runs, time, and the main reset strategies with their trade-offs.

ADesign a testing strategy for a product team of 40 developers working on one large API.design

A pyramid with clear ownership: fast unit tests on every save, integration and API tests in CI on every pull request against containerised dependencies, and contract tests (approved routes, OpenAPI diffs, consumer contracts) to protect clients. Add whole-API safety nets for security and DI, coverage reports per pull request to spot untested changes, flaky-test tracking with quarantine, time budgets for the suite, and smoke tests after each deployment.

How to answer:

Cover layers and speed, CI gates, contracts with clients, security nets, coverage use, flaky tests, and post-deployment checks.

CORS

FWhat is an origin, and when do two addresses have the same origin?concept

An origin is the scheme, host, and port of an address, such as http://localhost:5173. Two addresses have the same origin only when all three match; the path does not count. A page on port 5173 calling an API on port 5080 is a cross-origin call.

FWhat is CORS, and who enforces it?concept

Cross-Origin Resource Sharing. Browsers stop a page from reading answers from another origin unless the server allows it with the Access-Control-Allow-Origin header. The browser enforces it; curl, Postman, and other servers ignore it, so the API must still check tokens and permissions itself.

FA page shows 'Failed to fetch' but the same request works in Postman. How do you find out why?scenario

Open the browser's console and Network tab. A CORS refusal is explained in the console, for example "No 'Access-Control-Allow-Origin' header is present". The page's code only gets "Failed to fetch", on purpose, so the console is where the reason is.

MWhat is a preflight request, and when does the browser send one?concept

An OPTIONS request the browser sends before the real one, carrying Origin, Access-Control-Request-Method, and Access-Control-Request-Headers. It is sent for requests that are not simple: an Authorization header, a JSON body, or methods like PUT and DELETE. Without permission in the answer, the real request is never sent.

MWhere does UseCors go in the ASP.NET Core pipeline, and what breaks if it is too late?coding

Before UseAuthentication and UseAuthorization. The preflight carries no token, so if authorization runs first, the preflight gets 401 with no CORS headers and every browser call fails. In the SMS, moving it after UseAuthorization turned the preflight's 204 into a 401.

MAn unknown website's preflight gets 204 from your API. Is the API open to it?scenario

No. ASP.NET Core answers the preflight with 204 either way. What matters is the missing Access-Control-Allow-Origin header: without it the browser refuses, and the real request is never sent. Test for the header, not the status code.

SHow would you configure CORS for an API used by several websites across environments?design

One named policy with exact origins read from configuration: empty by default, the local front end in Development, the real websites per server. Validate the origins at startup (no path, no trailing slash), allow only the methods and headers the front ends use, expose only the response headers they must read, set a preflight max age, and cover it with tests that send preflights from allowed and unknown origins.

How to answer:

Cover exact origins from configuration, startup validation, least privilege for methods and headers, exposed headers, caching, and tests.

SWhy is AllowAnyOrigin risky, and when is it acceptable?concept

It lets any website read the API's answers inside your users' browsers, which matters most when the browser sends credentials automatically, such as cookies; ASP.NET Core refuses to combine it with AllowCredentials. It is acceptable for truly public, read-only data with no credentials, such as a public book catalogue, in a separate policy on those endpoints only.

How to answer:

Explain who is protected, the credentials rule, and a narrow per-endpoint policy for public data.

AMany teams' front ends call your organisation's APIs. How do you keep CORS correct and safe at scale?design

Avoid cross-origin calls where you can: serve the front end and API under one origin through a gateway or reverse proxy, or use a backend-for-frontend. Where CORS is needed, manage the allowed origins centrally per environment, validate them in CI and at startup, keep policies identical across environments except for origins, and test preflights in the pipeline. Never treat CORS as authentication; tokens and authorization stay on every API.

How to answer:

Cover same-origin options, central origin management, validation, environment parity, tests, and the limits of CORS as a security control.

Calling other services

FWhy should you not create a new HttpClient for every request?concept

Each new HttpClient opens new network connections, and closed ones linger for a while, so a busy server can run out of them. One HttpClient kept forever has the opposite problem: it never notices a changed DNS address. IHttpClientFactory reuses connections and renews them every two minutes by default.

FWhich HTTP failures are worth retrying, and which are not?concept

Retry errors that can pass: 5xx answers, 408, 429, timeouts, and broken connections. Do not retry 400, 401, 403, 404, 409, or 422: the request itself is wrong and will fail the same way again.

FWhat is a typed client?coding

A class that takes an HttpClient in its constructor and knows one service's API, registered with AddHttpClient<TInterface, TImplementation>(). The factory creates its HttpClient with the address, time limits, and retries set in one place, and the rest of the app only sees the interface.

MWhat are backoff and jitter, and why use both?concept

Backoff makes each wait longer than the last (about 1, 2, 4 seconds), so a struggling service gets time to recover. Jitter adds a random part to each wait, so many clients that failed together do not all retry at the same moment and overload the service again.

MWhat is an idempotency key, and when do you need one?concept

A unique id for one operation, sent in a header such as Idempotency-Key, the same on every attempt. If the service already handled that key, it returns the first result instead of doing the work again. You need it whenever you retry a request that changes something, such as a POST that sends a text or takes a payment, because a lost answer would otherwise cause a duplicate.

MExplain the three states of a circuit breaker.concept

Closed: calls go through and failures are counted. Open: after too many failures, every call fails at once without touching the service, for a break period. Half-open: after the break, one trial call goes through; success closes the circuit, failure opens it again.

SHow would you make an API's calls to a payment or messaging provider reliable?design

A typed client from IHttpClientFactory behind an interface; a time limit per attempt and a total limit; retries only for transient errors, with backoff and jitter; an idempotency key on every changing request; a circuit breaker; logs and metrics for retries and circuit events. Work that must not be lost goes into an outbox table first and is sent by a background job that can retry later. Tests replace the network with a scripted handler.

How to answer:

Cover the client, time limits, retry rules, idempotency, the circuit breaker, durable storage, observability, and testing.

SYour retries work, but during a one-hour provider outage messages were lost. What do you change?scenario

Retries cover seconds, not hours. Store each message durably before sending, in an outbox table with a status, in the same transaction as the business change. A background job sends pending rows, marks them sent, and retries failures later with growing delays, keeping the idempotency key, and alerts after too many failures.

How to answer:

Separate short retries from durable delivery, then describe the outbox, its job, and monitoring.

AMany services in your company call each other. How do you keep failures from spreading?design

Give every call a time budget shorter than the caller's own, and pass deadlines along. Retry only at one layer, so retries do not multiply through the chain, and cap them with retry budgets. Use circuit breakers and bulkheads (separate limits per dependency), idempotency keys for changing calls, and asynchronous messaging with durable queues where an immediate answer is not needed. Keep shared dependencies out of readiness checks, and watch retry and circuit metrics on dashboards.

How to answer:

Cover time budgets, where to retry, retry budgets, circuit breakers and bulkheads, idempotency, async messaging, health checks, and monitoring.

Files

FHow does an ASP.NET Core controller receive an uploaded file?coding

The client sends a multipart form, and the file part arrives as an IFormFile parameter whose name matches the form field. IFormFile gives the length, the claimed file name and content type, and OpenReadStream() to read the bytes.

FWhich parts of an uploaded file can you trust?concept

Only what actually arrives: its size, and its content after you check it. The file name, extension, and content type are chosen by the user's computer, so never use the name to save the file, and check the content itself, for example the header row of a CSV or the first bytes of a picture.

FHow do you make the browser download an API's answer as a file?coding

Return the bytes with the right content type and a Content-Disposition: attachment; filename=... header. In ASP.NET Core, File(...), PhysicalFile(...), or Results.Stream(..., contentType, fileDownloadName) set it from the file name you pass.

MHow do you limit the size of uploads, and what does the client get when a file is too big?coding

[RequestSizeLimit] on the action (or Kestrel's MaxRequestBodySize) stops reading beyond the limit, and form options limit multipart bodies. In an MVC action, the failed form read becomes a 400 "Request body too large" before the action runs. Check IFormFile.Length in code as well, since a test server may not enforce the limit.

MWhy might Validator.TryValidateObject miss the rules of a request record?concept

For a positional record, ASP.NET Core requires validation attributes on the constructor parameters, and throws if they are on the properties. Validator reads only properties, so it does not see them. Outside MVC you must read the parameters' attributes yourself, as the SMS's RecordValidator does, or validate differently.

MHow do you stream a large download instead of building it in memory?coding

Read rows one at a time (for example Dapper's QueryUnbufferedAsync as an IAsyncEnumerable) and write each to the response stream as it arrives, for example inside Results.Stream. The response goes out chunked, memory stays flat, and the client starts receiving data at once.

SDesign a CSV import of thousands of rows that must be safe to repeat and must never save half a file.design

Check the file (size, header), then every row with the same rules as the single-record endpoint, collecting errors by row. Bulk-copy valid rows into a staging table, check them against existing data, and apply one MERGE in a single transaction; any problem rolls everything back and returns every error. Matching on a natural key makes a repeated upload change nothing. Return counts of added, updated, and unchanged rows.

How to answer:

Cover the two stages of checks, error reporting by row, staging plus bulk copy, one transaction, the natural key for idempotency, and the summary.

SWhat security risks do file uploads and CSV exports bring, and how do you handle them?concept

Uploads: huge files (limit size), path traversal through file names (never use them; generate names), lying types (check content and signatures), malware (scan files that are stored or shared), and public folders (store outside them and serve through an endpoint that checks permissions). Exports: CSV injection, where a value starting with =, +, -, or @ runs as a formula; neutralise such values. Both need authorization.

How to answer:

Split upload and export risks, and give a defence for each.

AUsers upload large files (videos, scans) to your platform. How would you design it?design

Do not stream large files through the API servers. The API authorises the upload and returns a short-lived signed URL to object storage; the client uploads directly, in resumable chunks. A storage event triggers background processing: virus scan, type check by content, thumbnails or conversion, then the metadata row is marked ready. Downloads use signed URLs or a CDN. Set size and type limits, quotas per tenant, retention rules, and encryption at rest.

How to answer:

Cover direct-to-storage uploads with signed URLs, resumable chunks, asynchronous processing and scanning, metadata, downloads through a CDN, limits and quotas, and data protection.

Security

Users and passwords

MWhy do we store a password hash instead of the password, and how is a hash different from encryption?concept

A hash is a one-way function: easy to compute from the password, practically impossible to reverse. At login, the app hashes the typed password and compares hashes, so the real password is never stored. Encryption can be reversed with a key, so a stolen key exposes every password.

AHow would you design roles and permissions so they can grow with the system?design

Start with users, roles, and a user-role junction, as in the SMS. When permissions get finer, add a permissions table and a role-permission junction, and check permissions rather than role names in code. Data rules, such as "a parent sees only their children", are checked separately from roles.

How to answer:

Describe role-based access control and its limits, then the step to permission-based checks. Use SMS examples: Teacher and Accountant roles, and the parent-sees-own-child rule as a data-level check. Mention the trade-off: more flexibility means more admin screens and more testing of who can do what.

Authentication

FWhat is the difference between authentication and authorization, and between 401 and 403?concept

Authentication answers "who are you?"; authorization answers "are you allowed to do this?". A request without a valid token fails authentication and gets 401 Unauthorized. A signed-in user who may not do something fails authorization and gets 403 Forbidden.

FWhat are the three parts of a JWT, and can anyone read its contents?concept

A header (the algorithm, such as HS256), a payload of claims (such as sub, name, role, exp), and a signature, separated by dots. The header and payload are only base64url encoded, so anyone can read them; the signature only stops anyone changing them. Never put passwords or secrets in claims.

FHow should an API store passwords?concept

As a slow, salted hash, never as text or with a fast hash alone. The SMS uses ASP.NET Core Identity's PasswordHasher: PBKDF2 with SHA-512, a random salt for each password, and 100,000 rounds. To sign in, the typed password is hashed the same way and compared.

MWhat does a fallback authorization policy do, and why use one?concept

It applies to every endpoint that has no authorization attributes of its own. Setting it to RequireAuthenticatedUser makes the API secure by default: a new endpoint that someone forgets to protect still needs a signed-in user. Public endpoints opt out with [AllowAnonymous], such as login.

MWhich token settings does the API check on every request, and why set ClockSkew?coding

The signature (with the signing key), the issuer, the audience, and the expiry time (exp and nbf). ClockSkew is a grace period for clocks that differ between servers; its default is 5 minutes, so an expired token would still work for 5 more minutes. The SMS sets it to 30 seconds.

MWhere should a JWT signing key be kept, and what happens if it leaks?concept

Outside source control: user secrets while developing, and environment variables or a key vault in production. Anyone with the key can create a valid token for any user, including an admin. If it leaks, replace it at once; every token signed with the old key then stops working. The SMS also refuses to start without a key of at least 32 characters.

SA security review finds that your login says 'unknown user' for one mistake and 'wrong password' for another. Why is that a problem, and how do you fix it?scenario

It tells an attacker which user names exist, so they can focus password guessing on real accounts. Use one message for every failure ("User name or password is wrong."), and make both paths do the same work: the SMS still verifies against a dummy hash when the user does not exist, so the response time does not give it away either. Add rate limiting and lockout against guessing.

How to answer:

Explain user enumeration through messages and through timing, then the fix for each, and the extra defences against password guessing.

SA parent reports that a report-card link works without signing in. How did it happen, and how do you stop it happening again?scenario

That endpoint was protected one by one with [Authorize], and someone forgot it. Fix it now, then change the design: a fallback policy that requires a signed-in user everywhere, with [AllowAnonymous] only where needed. Add an automated test that calls every endpoint without a token and expects 401, and check the logs for anyone who used the open link.

How to answer:

Cover the immediate fix, the design change that makes the mistake impossible, the test that guards it, and the investigation of possible data exposure.

AAccess tokens last 60 minutes. How would you let users stay signed in longer, and sign them out at once when needed?design

Keep access tokens short and add refresh tokens: long-lived, random, stored hashed on the server with the user and device, and exchanged for a new access token (rotating the refresh token each time). Signing out, or blocking a user, revokes their refresh tokens; for instant cut-off, keep a short deny list of token ids (jti) until they expire, or shorten access token lifetimes. Larger systems often move sign-in to an identity provider using OpenID Connect.

How to answer:

Separate access and refresh tokens, explain storage and rotation, cover revocation and its delay, and say when a dedicated identity provider is worth it.

Authorization

FWhat is role-based access control?concept

Users belong to roles (in the SMS: Admin, Principal, Teacher, Accountant, Parent), and permissions are given to roles instead of to each user. The API checks the user's roles, sent as role claims in the token, before running an action.

FA signed-in user calls an endpoint their role may not use. What status should the API return?concept

403 Forbidden: the API knows who they are, but they are not allowed. 401 is only for a missing, invalid, or expired token. The app treats them differently: 401 means "sign in", 403 means "not allowed".

FWhy is hiding a button in the app not enough to protect a feature?concept

Anyone can call the API directly, with a copied token and a tool such as curl or the browser's developer tools. Every permission must be checked on the server with [Authorize]; hiding buttons is only for a tidy screen.

MWhat is the advantage of named policies over [Authorize(Roles = "...")] lists?design

The controller says what kind of user it needs (such as Teaching), and the roles for each policy are defined in one place. Adding a role or changing a permission is one line, instead of a search through every controller where one forgotten copy becomes a security hole.

MA controller has [Authorize(Policy = "Staff")] and one action has [Authorize(Policy = "ManageSchool")]. Who may call the action?coding

Only users who pass both policies: every authorization attribute on the controller and on the action must pass. In the SMS, that is Admin and Principal, who are in both Staff and ManageSchool.

MIn what order does ASP.NET Core run authorization and model validation, and why does it matter?concept

Authorization runs first, then model binding and validation. A refused user gets 403 even with an invalid body, so they never learn what a valid request looks like. In the SMS, a teacher posting an empty admission got 403, while the principal got 400 with the field errors.

SThe office changes a teacher into an accountant, but for a while she can still take attendance and cannot open fees. Why, and what are the options?scenario

Her roles are inside her access token, and the API does not look them up again on each request, so the change only arrives with her next token (up to 60 minutes in the SMS). Options: accept the delay and ask her to sign in again; shorten token lifetimes; or check a revocation list or the user's current roles on each request, at the cost of a database or cache lookup.

How to answer:

Explain claims in self-contained tokens, then weigh the options by how fast changes must apply and what each costs.

SHow do you make sure no role can do more than it should, as an API grows?design

Secure by default with a fallback policy, named policies in one file, and a data-driven test table with one row per role and sensitive endpoint, including the refusals. In the SMS, each row is a role, a request, and the expected status, chosen so no row changes data. Review new write endpoints for their policy before merging.

How to answer:

Combine design (defaults and named policies), automated proof (the permission table), and process (reviews), and explain why refusals need tests as much as successes.

ASchools want to define their own roles and permissions without a new release. How would you design it?design

Move from fixed roles to permissions: store Permissions, RolePermissions, and UserRoles per school, and make endpoints require permissions (such as Attendance.Take) instead of roles. A custom authorization policy provider can create a policy per permission name, and a handler checks the user's permissions, loaded at sign-in into the token or cached per user. Keep a few built-in roles as templates, audit every change to permissions, and decide how fast changes apply.

How to answer:

Explain the move from roles to permissions, how ASP.NET Core can check them dynamically, where the data lives per school, and how changes propagate and are audited.

FWhat is IDOR (insecure direct object reference)?concept

A bug where an API checks that a user may use an endpoint but not whether the record in the request belongs to them. Changing an id in the URL then shows someone else's data, such as a parent opening another child's report card by changing the admission number.

FWhat is the difference between a role rule and a record rule?concept

A role rule needs only the token: "is this user a teacher?". A record rule also needs the record being reached: "is she the class teacher of section 20?" or "is this parent linked to ADM-2017-0003?". Record rules usually read the route and ask the database.

FShould an API answer 404 or 403 when a parent asks for a student who is not theirs?concept

403, and the same 403 when the student does not exist at all. If real records gave 403 and missing ones 404, the answers would reveal which ids exist. The SMS answers 403 for both, and only users allowed to see a record ever learn whether it exists.

MWhat are an authorization requirement and an authorization handler in ASP.NET Core?coding

A requirement (IAuthorizationRequirement) is a small class that states a rule and holds its settings, such as which staff roles count. A handler (AuthorizationHandler<TRequirement>) checks it and calls context.Succeed when the rule holds. A policy lists requirements, so controllers only name the policy.

MHow can an authorization handler know which record a request is about?coding

For endpoints, context.Resource is the HttpContext, so the handler can read route values (such as admissionNumber or sectionId) and the query string. The SMS handlers read them, then ask the database whether the user is linked to that record. For rules that need a loaded object, you can instead call IAuthorizationService.AuthorizeAsync(User, resource, policy) inside the action.

MWhy should a handler take the user's own ids from the token and not from the request?concept

Anything in the request (body, query, headers other than the token) can be changed by the user. The token is signed, so its claims, such as guardian_id or teacher_id, cannot be changed without breaking the signature. The SMS compares the route's record with the ids from the token.

SA parent reports seeing another child's marks by changing a number in the app's address. What do you do?scenario

Confirm and fix the endpoint first: add a record rule that checks the parent is linked to the student in the route. Then search every endpoint with an id in its route for the same gap, add permission tests that try other families' ids, and check logs for who reached records they should not have. Report the exposure as the school's policy requires.

How to answer:

Cover the immediate fix, the systematic search for the same bug, tests that prevent it returning, and the investigation and reporting of the leak.

SRecord checks add a database query to many requests. How do you keep them fast and correct?design

Keep each check a tiny EXISTS query on indexed links (StudentGuardians, ClassTeachers, SubjectAllocations). Put small, stable facts in the token at sign-in, such as the user's teacher or guardian id, but not lists that change often. Cache answers per user for a short time if needed, and invalidate when links change. Measure: in the SMS each check reads only a few rows.

How to answer:

Balance speed against freshness: what goes in the token, what is queried, what is cached, and how changes reach the checks.

AList endpoints (such as all invoices) must also show each user only their records. How would you design that across a large API?design

Record rules on single-record endpoints are not enough for lists: the query itself must filter. Build the filter from the user (for example, only students linked to this guardian) in one shared place, such as a data-access layer that always adds it, or database row-level security with SESSION_CONTEXT set per request. Test lists with users who own nothing, one record, and many records.

How to answer:

Separate single-record checks from list filtering, compare doing it in the data layer with database row-level security, and explain how to make it impossible to forget.

Auditing

FWhat are audit columns, and why are they useful?concept

Columns such as CreatedAt, CreatedBy, UpdatedAt, and UpdatedBy that record when and by whom a row was created and last changed. They answer "who changed this?" for disputed data such as marks and payments, and they protect staff who made correct changes.

FWhy must the 'changed by' user come from the token and not from the request body?concept

The client decides what is in the body, so anyone could write someone else's id. The signed token cannot be changed, and the server carries the user from it into the database without the client touching it.

FWhat is SESSION_CONTEXT in SQL Server?concept

A set of key-value pairs that belongs to one connection, set with sp_set_session_context and read with SESSION_CONTEXT(N'key'). Statements, triggers, and DEFAULT constraints on that connection can read it, which lets the API tell the database who the user is.

MA column has a DEFAULT, but new rows still get NULL. Why?scenario

The INSERT names the column and passes NULL, and an explicit value, even NULL, wins over the default. In the SMS, the Dapper inserts leave CreatedBy out, so DF_..._CreatedBy fills it from the session's user.

MHow can a singleton service know the current request's user in ASP.NET Core?coding

Inject IHttpContextAccessor (registered with AddHttpContextAccessor). It finds the current request's HttpContext from anywhere, so a singleton such as the SMS's HttpCurrentUser can read the user's "sub" claim each time it is asked, even though the user changes with every request.

MWhy set the session user in the connection factory instead of in each repository?design

Every connection comes from the factory, so one hook covers every repository, Dapper call, and transaction, and nobody can forget it. The SMS adds a StateChange handler that runs sp_set_session_context with @read_only = 1 as soon as a connection opens.

SWith connection pooling, could one user's id stay on a connection and be used by the next request?scenario

Not with SESSION_CONTEXT: SQL Server resets a pooled connection's session state before it is reused, so the next user starts with NULL. The SMS proves it with a test that opens a connection with user 42, then opens another from the same pool without a user and reads NULL. @read_only = 1 also stops code on the same connection from changing the id.

How to answer:

Explain pooling and the reset, show how you would prove it with a test, and mention read-only values.

SMarks were changed after results were published, and the audit log has old and new values but no user. How do you fix this for the future?scenario

The application connects with one shared login, and nothing tells the database who the person is. Pass the signed-in user to every connection (SESSION_CONTEXT), let the triggers and defaults read it, and stamp UpdatedBy in updates. Add a test that a change through the API records the user, and consider blocking changes to published results without a recorded reason.

How to answer:

Explain why the user was missing, describe the end-to-end fix, how to verify it, and a process rule for sensitive changes.

AHow would you design auditing for every important table in a large system?design

Decide what must be audited (who, when, what changed, from where), then choose a mechanism: triggers that write before-and-after values (as tr_Marks_Audit does), SQL Server temporal tables for full history, or change data capture feeding a separate audit store. Pass the user and request id on every connection, protect the audit data from changes (separate permissions, append-only), set retention rules, and give the office a way to search it.

How to answer:

Compare the mechanisms by detail, cost, and tamper resistance, and cover identity propagation, retention, and how people will use the audit data.

Rate limiting

FWhat is rate limiting, and what does it protect against?concept

Capping how many requests a caller may make in a period. It slows password guessing on sign-in, stops one client (or a buggy app in a loop) from taking everyone's share, and limits the damage of floods. The SMS allows 5 sign-ins per minute per address and 300 requests per minute per user.

FWhat should an API return when a request is rate limited?concept

429 Too Many Requests, with a Retry-After header saying how many seconds to wait when the limiter knows it, and a body in the API's usual error shape. Well-behaved clients wait instead of retrying at once.

FCompare the fixed window, sliding window, and token bucket limiters.concept

Fixed window: N requests per window, reset when it ends; simple, but bursts can cluster at the edge. Sliding window: N requests in any window, counted in segments; smoother. Token bucket: a bucket of N tokens refilled at a steady rate; allows short bursts with a steady average. The SMS uses a fixed window for sign-in and a token bucket for general traffic.

MWhat is a partition in ASP.NET Core rate limiting, and how do you choose the key?design

A partition is whose count a request uses, chosen by a key computed from the request. Before sign-in the only key is the client address; once signed in, the user id is fairer, because many users can share one address. The SMS uses "user:{sub}" when signed in and "ip:{address}" otherwise.

MWhere must app.UseRateLimiter() go in the pipeline, and why?coding

After UseAuthentication (and after routing, which minimal hosting adds early), so the limiter can see the signed-in user for per-user limits and the endpoint's [EnableRateLimiting] policy. Placed before authentication, every request would count as anonymous.

MWhy are rate-limit tests often flaky, and how do you avoid it?scenario

In tests every request comes from the same address and the suite makes many sign-ins, so a real limit is hit at random. Raise the limits in the shared test setup, and test the limiter on purpose with a separate server configured with small limits, as the SMS's RateLimitTests does.

SShould you protect sign-in with account lockout or with rate limiting?design

Lockout blocks the account after N failures, which also lets an attacker lock a real user out on purpose. A rate limit per address slows the attacker's address without touching the user, but a guesser with many addresses gets N guesses each. Combine them: a per-address limit first, a softer per-account protection (delays or a long lockout only after many failures), and alerts on repeated failures.

How to answer:

Compare who each defence slows down, how each can be abused, and propose a layered design.

SAt 8:00 every teacher signs in from the school's one network address and many get 429. What do you change?scenario

The sign-in limit is per address, and the whole staff room shares one. Raise the per-address sign-in limit for that school's deployment (it is configuration), and keep guessing slow with a per-account protection, such as a short lockout or growing delays per user name, plus alerts. Check the rejection logs to confirm the cause first.

How to answer:

Diagnose from the logs, explain why the partition key causes it, and give a fix that keeps the security goal.

AThe API runs on several servers behind a load balancer. How do you make rate limits correct across all of them?design

The built-in limiter counts in each server's memory, so N servers allow roughly N times the limit. Options: a gateway or reverse proxy that limits in one place before the servers; a shared store (such as Redis) that all servers count in; or dividing each server's limit by the number of servers as an approximation. Keep per-user limits in the API, where the user is known, and coarse per-address limits at the edge.

How to answer:

Explain why in-memory counts multiply, compare edge limiting, shared counters, and approximations, and say which limits belong where.

System Design

Non-functional requirements

AWhich non-functional requirements change when the SMS goes from one school to 1,000 schools?design

Data isolation becomes critical: one school must never see another's data. Load peaks multiply, for example every school taking attendance between 8 and 9 AM. Availability, backups and restore per school, deployments without downtime, security reviews, and the cost per school all become explicit requirements with numbers.

How to answer:

List the categories (isolation, scalability, availability, recoverability, security, cost) and give one SMS number for each, such as "attendance save under 1 second at 8 AM for 1,000 schools". Then name the design consequence: a tenant column or database per school, caching, and horizontal scaling, and the trade-off between shared and separate databases (cost against isolation).

Reporting

AHow would you separate day-to-day school operations from heavy reporting when the SMS serves 1,000 schools?design

Keep the normalized transactional database for daily work such as attendance and fees. Send reporting to a separate copy built for reading: a read replica for simple reports, or a data warehouse with denormalized tables refreshed on a schedule. Heavy reports then never slow down a teacher saving attendance.

How to answer:

Name the two workloads (many small writes vs few large reads) and why one design cannot serve both well. Describe the options from cheapest to most powerful: indexed views, read replicas, then a warehouse. State the trade-off: reports become slightly delayed (eventual consistency) in exchange for fast, safe daily operations.

Multi-tenant SaaS

FWhat is a SaaS product, and what is a tenant?concept

SaaS (software as a service) means one company runs one system and many customers use it over the internet, usually for a monthly fee. Each customer is a tenant: it shares the system with the others but must only ever see its own data. In the SMS, each school is a tenant.

FWhat is the difference between functional and non-functional requirements? Give an example of each.concept

Functional requirements say what the system does, such as "a school admin can add a teacher". Non-functional requirements say how well it does it, such as "95% of requests answer in under 300 ms" or "99.9% availability". Non-functional ones need numbers, or nobody can test them.

FWhat is an architecture decision record (ADR)?concept

A short document, kept next to the code, that records one important decision: the context, the options considered, the choice, and its consequences. It explains later why the system looks the way it does, so the same debate does not have to be repeated.

MCompare shared database, schema per tenant, and database per tenant.concept

Shared database with a tenant column: one schema, cheapest, simplest upgrades, but a missed filter leaks data and one busy tenant can slow others. Schema per tenant: better separation, but every table is copied per tenant. Database per tenant: strongest isolation and easy per-tenant restore, but many databases to upgrade, back up, monitor and pay for, and cross-tenant reports are hard.

MHow would you estimate the database size of a system before it is built?scenario

Measure bytes per row on real or realistic sample data (data plus every index, for example from sys.allocation_units or sys.dm_db_index_physical_stats), then multiply by rows per year from written assumptions: tenants, users, events per user. Keep the assumptions in one place so the estimate can be rerun. For the SMS: about 100 bytes per attendance row, 176 million rows a year, about 19 GB.

MWhy design for the peak hour instead of the average load?concept

Users judge the system at its busiest moment. In the SMS, morning attendance is about 11 requests a second but results day is about 444, 40 times more; a system sized for the average would fail exactly when parents need it. Size compute, connection pools and caches for the peak, and use the quiet hours for batch work.

SYour company sold its app to each new customer by copying the code and database. What problems follow, and how do you fix them?scenario

Each copy drifts: fixes must be repeated per customer, some copies miss security fixes, and upgrades become projects. Move to one multi-tenant system: one code base, one schema with a tenant id, per-tenant settings instead of per-tenant code, and a migration plan that moves customers one by one with their data verified.

How to answer:

Name the operational and security costs of copies, then describe the target design and a safe migration path.

SYou chose a shared database with a SchoolId column. What risks does that bring, and how do you control them?design

Data leaks from a missing filter, and noisy neighbours. Control leaks with two layers: tenant filtering in every repository and database-level row-level security, plus tests that try to read another tenant's data. Control noisy neighbours with indexes that start with the tenant id, per-tenant rate limits, and background or serialized heavy jobs. Keep the option to move a very large tenant to its own database later.

How to answer:

Name each risk with a concrete failure, then a preventive control, a detective control, and an escape hatch.

ADesign the tenancy model for an education platform expected to grow from 50 to 10,000 schools.design

Start with a shared database and a tenant id for cost and simple operations, with isolation enforced in the application and the database. Design for movement: tenant id in every key and index, a tenant catalogue that maps each tenant to a database, and tooling to move one tenant. As it grows, shard tenants across several databases, and give the largest or most regulated tenants their own database, all behind the same code.

How to answer:

Show how the model evolves with scale and cost, covering isolation, routing through a tenant catalogue, sharding, per-tenant exceptions, and operations such as upgrades and backups.

Leadership

Project discussion

FTell me about a project you have built.behavioral

Use a clear structure: the problem, who uses it, your role, the technology, one hard problem you solved, and the result. Keep it to about two minutes. For example: "I built a School Management System with SQL Server, C#, and ASP.NET Core. The hardest part was making sure attendance could not be saved twice for the same student and day."

MHow do you explain your project's architecture in an interview?behavioral

Go layer by layer from the user to the data: the client, the API, the business logic, and the database, naming the technology for each. Then follow one real request through all of them, such as a teacher saving attendance. Finish with one design decision and why you made it.

Planning

SThe school wants attendance, fees, exams, transport and hostel modules live in three months with two developers. What do you build first?scenario

Order the work by dependency and value. Masters, students, and enrollment come first because every other module needs them. Then attendance (used every day) and fees (money and legal records), then exams. Transport and hostel move to a later phase, and the agreed scope is written down and delivered in small increments.

How to answer:

Name the principle (dependencies first, then business value and risk). Walk through the SMS module order with the reason for each. Then state the trade-off honestly: cutting scope is acceptable, cutting data integrity or security is not, and the client must agree in writing to what moves to phase two.

SHow do you decide what is in scope and what is out of scope?behavioral

Rank features by business value, dependencies, risk, and the deadline, for example with Must, Should, Could, and Won't. Must-haves and their dependencies go in; the rest goes on a written out-of-scope list. The client agrees to that list, so new requests become planned changes instead of silent extra work.

How to answer:

Explain the ranking method, then show the SMS example: payment gateways, transport, and timetables are out of Part 1 because the core school records come first. Close with the trade-off: a smaller scope delivered well beats a large one delivered late, and scope is revisited every release.

Requirements

MWhat do you do when a requirement is unclear?behavioral

Ask specific questions with examples instead of guessing, and where possible watch how the work is done today. Write down your assumptions and get them confirmed by the person who owns the requirement. A five-minute question is cheaper than a week of rework.

SAfter the database is built, the principal says attendance must be taken per period, not per day. How do you handle it?scenario

First assess the impact: tables, API endpoints, screens, reports, and existing data that must be migrated. Then give an estimate and discuss priority and timeline with the client as a change request. Once agreed, update the requirements, the design, and the tests before changing code.

How to answer:

Show a calm process: impact analysis, estimate, agreement, then change. Use the SMS detail: AttendanceRecords needs a period column and a new unique rule, and old daily records need a migration decision. Mention the trade-off between a quick patch and a clean redesign, and how asking "show me how you do it today" earlier would have caught it.