User requirements
Question: What are user requirements?
User requirements describe what the people using the software need the system to do. They are written from the user's point of view
and should focus on outcomes instead of implementation details. A strong answer explains that requirements guide design decisions,
testing, and review because they define what "working" means before code is written.
A good requirement is clear, testable, and tied to a real user goal. It should avoid vague language such as "make it easy" unless the
answer also explains how ease will be measured. For example, "The user can filter active animal records by species and status" is more
useful than "The app should have good search" because it identifies the action, the data, and the expected result.
Example answer detail: The user can search active animal records by name or species and see matching records without archived records mixed in. This can be tested by loading sample records, typing a search term, and confirming only matching active records appear.
Functional requirements
Question: What is a functional requirement?
A functional requirement describes a specific action or behavior the system must perform. It answers the question "What must the software do?"
Examples include adding a record, saving a file, calculating a fee, filtering a table, printing a report, or validating a form before submission.
In a written answer, separate functional requirements from design preferences. "The user can create, edit, archive, and restore records" is
functional because each action changes or retrieves data. "The screen is attractive" is not functional unless it is converted into a measurable
interface requirement.
Example answer detail: A rescue-management app might require that the user can add a new animal with a species, birthday, intake date, location, status, and adoption fee. The app must then display the new record immediately and save it so the record is still available after restart.
Non-functional requirements
Question: What is a non-functional requirement?
A non-functional requirement describes the quality level or constraint the system must meet. Instead of saying what feature exists, it describes
how well the system must perform. Common areas include performance, reliability, usability, accessibility, maintainability, security, compatibility,
and data durability.
Strong answers use measurable language. "The app should be fast" is weak because it does not define success. "The app should load 1,000 records
in under two seconds on the target machine" is stronger because it can be tested. Non-functional requirements matter because a feature can exist
but still fail if it is slow, confusing, fragile, or unsafe.
Example answer detail: If a desktop app stores records in a CSV file, a reliability requirement could say that saving should not corrupt the existing file if one row has invalid data. The app should report the error clearly and preserve recoverable records.
Acceptance criteria
Question: How are acceptance criteria different from requirements?
Requirements state what the system must do. Acceptance criteria define the exact conditions that prove a requirement has been met. They turn a
general goal into checkable statements, which makes review and testing more objective.
Good acceptance criteria are written in observable terms. They should avoid hidden assumptions and should include success conditions for normal
and failure paths. For example, a requirement might say "The app lets the user archive a record." Acceptance criteria would state that the record
disappears from the active view, appears in the archived view, is saved to storage, and can be restored later.
Example answer detail: For a search feature, acceptance criteria could include: matching records appear as the search text changes, archived records remain excluded unless the archived view is selected, and clearing the search restores the full active list.
Test plans
Question: What belongs in a test plan?
A test plan identifies what will be tested, how it will be tested, what data will be used, what result is expected, and how pass or fail will
be decided. It should cover normal cases, invalid input, boundary values, and regression checks after changes. A good test plan is specific enough
that another developer can follow it and reach the same conclusion.
A complete answer should mention test case ID or description, steps, test data, expected result, actual result, and status. The plan should also
include setup information, such as which sample file or starting records are required. For a data app, tests should include create, read, update,
delete or archive, search, save, load, and invalid-data behavior.
Example answer detail: Add an animal with a valid birthday and verify that the saved adoption fee matches the age rule. Then close and reopen the app to confirm the value was written to storage and reloaded correctly.
Boundary testing
Question: What are boundary values, and why should they be tested?
Boundary values are inputs at the edge of an allowed range or just outside it. Many defects happen at boundaries because code often uses
comparisons such as less than, less than or equal to, greater than, or greater than or equal to. Testing only average values can miss these errors.
A strong answer should include values below the boundary, exactly on the boundary, and above the boundary. If a fee changes at one year old,
test an animal just under one year, exactly one year, and just over one year. If a field allows 50 characters, test 49, 50, and 51 characters.
Example answer detail: If an adoption fee must be between 0 and 1,000, test -1, 0, 1, 999, 1,000, and 1,001. The app should accept only the valid range and show a useful message for invalid values.
Math in programming
Question: Why does math matter in application logic?
Math is used for calculations, comparisons, sorting, age rules, totals, indexes, percentages, dates, measurements, and data summaries. Even when
an app does not look mathematical, it often relies on arithmetic and logical comparisons to make correct decisions.
A strong answer should mention boundaries. For example, if a fee changes when an animal turns one year old, the program must handle the exact day
of the birthday correctly. Off-by-one errors, rounding errors, and date calculations are common sources of bugs. Clear formulas and test cases make
the logic easier to trust.
Example answer detail: A date-of-birth calculation can decide whether an animal is young, senior, or standard fee. The test data should include dates just before, on, and just after each age boundary.
Variables
Question: What is a variable?
A variable is a named storage location for a value used while a program is running. Its type controls what kind of value it can hold and what
operations are valid. For example, a number can be added, a string can be combined or searched, and a Boolean can be used in a condition.
Variables make code readable because they give meaning to values. A clear variable such as archivedCount explains its purpose better
than a vague variable such as x. In a written answer, mention that variable values may change over time, while constants are used when
a value should remain fixed.
Example answer detail: archivedCount can store how many records were moved during a bulk archive action. The program can increment it after each successful archive and display the total when the action finishes.
Data types
Question: Why are data types important?
Data types tell the program what kind of data a value represents and which operations are allowed. Common types include strings for text, integers
for whole numbers, decimals for currency-like values, Booleans for true/false decisions, dates for calendar values, and objects for structured data.
Choosing the right type prevents bugs. A phone number may look numeric, but it is usually better as text because it can contain leading zeroes,
spaces, symbols, or country codes and should not be used in arithmetic. A price should not be stored as plain text because calculations and
comparisons become harder and more error-prone.
Example answer detail: An adoption fee should use a numeric type such as decimal because the app may compare, format, or calculate it. A status can use an enum to restrict values to known options instead of allowing any random text.
Constants
Question: Why should repeated fixed values often become constants?
A constant is a named value that should not change while the program runs. Constants are useful for repeated values such as default fees, file names,
maximum lengths, or status labels. They make code easier to read and easier to update.
Without constants, code can end up with unexplained literal values repeated in many places. These are often called magic values because their meaning
is not obvious. If the value changes later, every copy must be found and updated. A constant gives the value one clear definition and a meaningful label.
Example answer detail: Instead of writing 250 in several fee calculations, define a constant such as DefaultAdoptionFee. The code then explains the business meaning of the value and reduces update mistakes.
File input and output
Question: How does file I/O support an app?
File input reads stored data into memory so the program can display and work with it. File output writes current data back to storage so changes
are not lost when the app closes. File I/O is often used in smaller desktop apps because it is simple to deploy and does not require a database server.
Reliable file I/O needs a known format, validation, error handling, and a plan for missing, empty, or corrupted files. A strong answer should mention
that the app should not crash if the file is absent. It can create a new file, load an empty list, or show a clear error message depending on the requirement.
Example answer detail: A CSV file can store one animal per line with a header row and escaped commas. On startup, the app reads each row into an object; after edits, it writes the current object list back to the file.
CSV storage
Question: What are the strengths and weaknesses of CSV storage?
CSV storage is a plain-text table format where each row represents a record and columns are separated by commas. It is easy to inspect, copy, and
include with a project. It works well for small datasets and simple review because the data can be opened in a text editor or spreadsheet program.
CSV also has limitations. It does not enforce relationships, data types, uniqueness, or constraints by itself. Special care is needed when values
contain commas, quotes, or line breaks. It can also become inefficient or risky if many users write to the same file at once. A strong answer should
compare CSV with a database and explain that CSV is acceptable when the data size and requirements are modest.
Example answer detail: A record with a note like Needs quiet home, no stairs contains a comma, so a proper CSV writer must quote or escape the field. Splitting each line with a simple comma split can break the data.
Algorithms
Question: What is an algorithm?
An algorithm is a defined set of steps for solving a problem or completing a task. It can be written in code, pseudocode, a flowchart, or plain
structured language. A good algorithm is correct, understandable, finite, and efficient enough for the expected data size.
In a written answer, explain the input, processing steps, decisions, and output. If the algorithm includes loops or branches, describe when they start
and stop. If there are edge cases, such as an empty list or duplicate records, state how the algorithm handles them.
Example answer detail: To show the three oldest animals by species, group records by species, sort each group by birthday from oldest to newest, take the first three records from each group, and display the combined result. If a group has fewer than three animals, show all available records.
Arrays and lists
Question: When would you use a list instead of an array?
Arrays are fixed-size collections. They are useful when the number of items is known and stable. Lists can grow or shrink as records are added
or removed, which makes them more convenient for apps where users create, edit, archive, restore, or delete records while the program is running.
A strong answer should compare behavior, not just syntax. Arrays may be slightly simpler for fixed groups, while lists provide methods such as
Add, Remove, Find, and Where through collection APIs. For most CRUD-style desktop apps, a list
is a natural in-memory structure.
Example answer detail: Load CSV rows into a List<Animal>, remove one record by ID, then save the list back to disk. This is easier than resizing an array every time a row is added or removed.
Control structures
Question: What are control structures?
Control structures decide the order code runs in. Common examples include if, else, switch, for,
foreach, and while. They let programs branch, repeat work, skip work, and stop when conditions are met.
Branching structures are used when the program must choose between paths. Looping structures are used when the same operation must happen for many
items or until a condition changes. A good written answer should include both types and explain why they are necessary for real application behavior.
Example answer detail: An if statement can decide whether a form is valid before saving. A foreach loop can check every record in a list and display only records matching the selected species.
Searching and filtering
Question: How does searching or filtering usually work in an app?
Searching and filtering reduce a larger dataset to the records that match user input or selected criteria. The app usually starts with a full in-memory
collection, applies one or more conditions, and displays the matching subset. Filtering should not destroy the original data; it should only change what is visible.
A strong answer should mention case handling, empty search text, combined filters, and status filters. For example, searching for text should usually
ignore uppercase/lowercase differences. Clearing the search box should restore the unfiltered view. If the app has active and archived records, the
filter logic should respect the current view.
Example answer detail: If the user searches for "cat" while the active view is selected, the app can return records where the species or description contains "cat" and where the status is not archived.
Relational database design
Question: What is relational design?
Relational design organizes data into tables made of rows and columns. Each table represents one kind of entity, such as animals, adopters, staff,
appointments, or locations. Relationships connect tables so data does not need to be repeated unnecessarily.
The purpose is to reduce duplication and protect consistency. If adopter contact information is stored in one adopter table, then many adoption records
can refer to that adopter by ID. Updating the adopter's phone number then happens in one place instead of across many duplicated rows.
Example answer detail: Even when an app uses flat files, thinking in records, fields, unique IDs, and constraints improves the design. It encourages consistent IDs, clear columns, and predictable validation rules.
Primary and foreign keys
Question: What are primary keys and foreign keys?
A primary key is a field, or combination of fields, that uniquely identifies one row in a table. A foreign key is a field that points to a primary key
in another table. Together, they create reliable relationships between records.
A strong answer should explain why names or descriptions are usually poor keys. They can change and may not be unique. IDs are better because they are
stable and designed for identification. Foreign keys also help prevent invalid references, such as an adoption record pointing to an adopter that does not exist.
Example answer detail: An AnimalId can uniquely identify each animal. An Adoption table can store that AnimalId as a foreign key so the adoption record is linked to the correct animal.
Validation
Question: What is input validation and why is it important?
Input validation checks whether data entered by a user or loaded from a file is complete, correctly formatted, and reasonable before the program uses it.
Validation protects data quality and prevents crashes or incorrect calculations.
There are several kinds of validation. Required-field validation checks that important fields are not blank. Type validation checks that a date, number,
or enum value can be parsed. Range validation checks values such as fees or dates against allowed limits. Business-rule validation checks rules such as
"the intake date cannot be before the birth date."
Example answer detail: Before saving an animal record, the app can verify that the species is selected, the birthday is a valid date, the fee is not negative, and the status belongs to the allowed status list.
Error handling
Question: What is error handling?
Error handling is the code and design that lets a program respond safely when something goes wrong. Errors may come from invalid input, missing files,
failed parsing, unavailable resources, permission problems, or unexpected state. Good error handling prevents crashes and helps the user recover.
A strong answer should distinguish between preventing errors and handling errors. Validation prevents many bad inputs before they reach deeper logic.
Exception handling responds to failures that still occur. The message shown to the user should be clear enough to guide action, while technical details
can be logged or kept in a developer-facing location.
Example answer detail: If a data file is missing, the app can create an empty dataset and show a short message. If the file exists but one row cannot be parsed, the app can skip that row, report the issue, and continue loading valid records.
Frontend and backend
Question: How do frontend and backend responsibilities differ?
The frontend is the part of the application the user interacts with. It includes screens, forms, buttons, lists, layout, messages, and direct interaction
behavior. The backend is the part that stores data, applies business rules, validates input, performs calculations, and provides data to the frontend.
In a desktop app, the same project may contain both frontend and backend code. For example, a WPF window can display the interface while service classes
load data, save files, and apply rules. The important idea is separation of responsibility: UI code should not contain every storage detail, and storage
code should not depend on button layout.
Example answer detail: A form may collect an animal's data on the frontend. A service layer can validate the data, assign an ID, calculate a fee, and write the record to storage.
APIs
Question: What is an API?
An API, or application programming interface, is a defined way for one part of software to communicate with another. It describes what operations are
available, what inputs they accept, and what outputs or results they return. APIs can exist inside one program or across a network.
A strong answer should avoid describing APIs only as web endpoints. A class method such as LoadAnimals() is also an interface used by other
code. The value of an API is that callers do not need to know every internal detail; they only need to follow the contract.
Example answer detail: A data service might expose LoadAnimals and SaveAnimals. The UI can call those methods without knowing exactly how CSV parsing or writing is implemented.
Object-oriented programming
Question: What are core OOP ideas?
Object-oriented programming models software as objects that combine state and behavior. State is the data an object stores, and behavior is what the
object can do through methods or properties. Important ideas include classes, objects, encapsulation, inheritance, polymorphism, and composition.
In practical apps, encapsulation and composition are often the most visible. Encapsulation keeps related data and behavior together while limiting
unsafe access. Composition builds larger behavior by combining smaller objects, such as a screen using a data service rather than handling every file
operation itself.
Example answer detail: An Animal class can store an ID, species, birthday, status, and fee-related behavior. A separate service can manage loading and saving many Animal objects.
Class instantiation
Question: What happens when a class is instantiated?
Instantiating a class means creating an object from a class blueprint. In C# or Java, this commonly happens with the new keyword. The class
defines fields, properties, methods, and constructors; the object is the live instance that stores its own state.
During instantiation, the runtime allocates memory, initializes fields to default values, runs field initializers and base-class construction, executes
the selected constructor, and returns a reference to the new object. That reference can be stored in a variable and used to call methods or access properties.
Example answer detail: When code creates new Animal(), the object starts with default property values. The program can then assign values such as species, status, and intake date before adding it to a list.
Constructors
Question: What is a constructor?
A constructor is a special method that runs when an object is created. It prepares the object for use by setting required values, validating arguments,
assigning dependencies, and establishing safe defaults. Constructors help prevent objects from existing in an incomplete or invalid state.
A strong answer should mention that constructors can have parameters. Parameters allow the caller to provide required information immediately. If a value
is required for the object to work, accepting it in the constructor is usually safer than relying on the caller to remember to set it later.
Example answer detail: A service constructor might receive a file path. If the path is empty, the constructor can throw an exception or choose a default path before any load or save method runs.
Encapsulation
Question: What is encapsulation?
Encapsulation means keeping related data and behavior together while controlling how the data can be accessed or changed. It helps protect object state
from accidental misuse and makes code easier to maintain.
In C#, encapsulation often uses properties, private fields, methods, and access modifiers such as private, public, and
internal. The object can expose safe operations while hiding internal details. This allows the implementation to change without forcing
every caller to change.
Example answer detail: Instead of letting any code set an invalid status string, an object can expose a status property with restricted values or use an enum. That keeps records consistent across the app.
Debugging
Question: What is debugging and how should it be approached?
Debugging is the process of finding, understanding, and fixing defects in software. A disciplined approach starts by reproducing the problem, narrowing
the failing area, inspecting data and control flow, applying a focused fix, and then retesting the original case plus nearby cases.
Strong answers mention evidence. Guessing can waste time. Breakpoints, logs, error messages, stack traces, small test inputs, and code review all help
reveal what the program is actually doing. After a fix, regression testing matters because a change can solve one problem while creating another.
Example answer detail: If saving produces an empty file, check whether the list contains records before saving, whether the save method receives the correct path, whether exceptions are thrown, and whether the file writer is being closed or disposed correctly.
Deployment
Question: What should deployment include?
Deployment is the process of preparing software so another person can run and review it outside the developer's editor. It should include the executable
or build output, source files, project files, required data files, instructions, and any environment details needed to run the application.
A strong written answer should mention repeatability. The reviewer should not need to guess which file to open, which framework version is required,
or where sample data belongs. If the app depends on a specific runtime, folder structure, or startup file, that information should be documented clearly.
Example answer detail: A desktop submission can include a release build folder, the full source project, a README with run steps, sample CSV data, and screenshots showing the main workflows.
Documentation
Question: What makes developer documentation useful?
Useful documentation tells another person how to understand, run, test, and maintain the project. It should be accurate, concise, and close to the
actual behavior of the software. Documentation is not a replacement for working code, but it reduces confusion and makes review faster.
A strong answer can mention setup instructions, feature summaries, data format notes, known limitations, test notes, screenshots, and troubleshooting
steps. Documentation should avoid vague claims and should include exact commands or paths when those details are important.
Example answer detail: A README can explain the app purpose, required framework, how to open the solution, how to run the app, where data is stored, and how to verify each main workflow.
Security basics
Question: What security ideas should a basic app consider?
Security means protecting data, users, and the system from accidental or intentional misuse. Even a small app should validate input, avoid trusting
external files blindly, handle errors without exposing unnecessary technical details, and store sensitive information carefully.
A strong answer should connect security to real behavior. If an app opens a file, it should handle unexpected content safely. If it stores personal
or private data, access and retention should be considered. If it uses passwords or tokens, they should not be hard-coded in source files or displayed
in plain error messages.
Example answer detail: A data import feature should validate each row before using it, reject impossible dates or invalid enum values, and show a clear message instead of crashing or exposing a stack trace to the user.
End-to-end development
Question: What does end-to-end development mean?
End-to-end development means building the full path from user input to validated logic, storage, output, documentation, and deployment. A feature is
not complete when only the screen exists. It must handle realistic data, save changes correctly, recover from mistakes, and be usable by someone other
than the original developer.
A strong answer should describe the whole workflow. For example, adding a record includes displaying the form, validating fields, creating the object,
adding it to the collection, refreshing the interface, saving it to storage, reloading it later, and documenting how the feature works. Testing should
cover the full path, not only one method.
Example answer detail: If a user archives a record, end-to-end behavior includes clicking the command, confirming the record moves to archived status, updating all counts and filters, writing the change to storage, and showing the archived record after restart.