12 Viva Questions Examiners Ask About Your Final Year Project
Viva questions cluster into a few recognisable families, and in most vivas every one of them ends with the same follow-up: show me where that happens in the code.
Search for viva questions for final year project and you will find lists of a hundred questions with a hundred canned answers. Memorise all of them and you can still fail, because the examiner is not testing whether you can define normalisation. They are testing whether the project on the screen was built by the person sitting in front of them.
Examiners are more predictable than those lists suggest. Not in format - a viva can be a ten-minute checklist or an hour of grilling, depending on your institution and your examiner - but in substance. The questions that actually move marks tend to cluster into a small number of families. I count six. The twelve questions below are drawn from those six families, and each of them has the same follow-up waiting behind it: show me where that happens in the code.
That follow-up is why you cannot bluff. And it is why the examiner is really checking three things, in this order. Did you build it. Do you understand what you built. Do you know what is wrong with it. Most students prepare only for the second one and defend the project as if it were finished and perfect, which is a mistake, because an examiner who cannot find a limitation you already know about will start hunting for one you do not.
The six families every viva question comes from
- Why this stack. Did you choose it, or did the tutorial choose it for you?
- Why this database, this model, this algorithm. Do you understand the shape of your own data?
- What breaks at scale. Can you name your bottleneck in one sentence?
- Where does it fail. Have you ever watched your own project break?
- What would you do differently. Can you criticise your own work without collapsing?
- Show me where that happens in the code. Can you navigate the repository you say you wrote?
Why "I followed a tutorial" is the answer that sinks you
Not because learning from a tutorial is a sin. Everyone starts from someone else's code. The problem is what the sentence reveals: the decision was made by a person who is not in the room, and there is nobody present who can defend it. Once an examiner hears it, the rest of the viva stops being a conversation and becomes an audit.
The repair is available even the night before, because you can make the decision now that you did not make then. You did not choose JWT over sessions. Fine. But you can look at what you have and say the true thing: I started from a reference implementation, here is why stateless tokens work for an app with a web and a mobile client, and here is where it hurts, because a token stays valid after logout until it expires. If I did it again I would add a deny-list in Redis. That is an engineer talking. "I followed a tutorial" is a passenger talking.
Prepare by writing down every decision you made, and the alternative you rejected
The single highest-leverage preparation is not re-reading your report. It is a decision log. Walk your repository and list every fork in the road you passed: language, framework, database, auth, hosting, model, loss function, threshold, even the chart library. For each one write four things: what you picked, what you rejected, why, and what it costs you. A couple of dozen rows. The examiner's questions land on rows in that table. An evening on this file is worth three evenings of re-reading your report, and any row where the honest reason is "the tutorial did it" is your revision list: either work out why it is defensible, or be ready to say plainly that you would choose differently now.
The trade-off vocabulary examiners respond to
Examiners are engineers. They are listening for whether you can name what you traded away, because every real decision costs something, and a student who claims their choice has no downside has not understood the choice. Learn to speak in pairs - and use the pair that is actually true of your system. Do not reach for CAP unless your system is genuinely distributed. If your whole backend is one Postgres instance, there is no partition for you to be unavailable under, and an examiner will ask you which two nodes you had in mind.
- Correctness versus throughput. The order write and the stock decrement happen in one transaction, with a row lock on the stock row, so the system refuses an order rather than overselling. The cost is that concurrent checkouts on a hot item serialise behind that lock. I chose refusing over overselling.
- Latency versus cost. Inference runs inside the request, which keeps predictions fresh and adds a few hundred milliseconds. Precomputing nightly would serve faster and read staler.
- Precision versus recall. The classifier feeds a human reviewer, so a missed fraud costs more than a false alarm. I moved the threshold below 0.5 and accepted the extra alarms.
- Reads versus writes. Name the indexes your dashboard query actually uses, and the before-and-after time you measured on a realistically sized table; every insert pays a little for them, and on a read-heavy app that is a trade worth making. An index that no query in your codebase touches is not a trade-off, it is dead weight - and an examiner who spots it will ask what it is for.
- Coupling versus duplication. I kept one service and duplicated a validation rule in two places rather than build a shared package for a codebase this size.
Twelve viva questions, and how to answer them from your own code
1. Why did you choose this stack?
The answer that sinks you is a feature list: React is component-based, Node is fast, it has a large community. Every project in the room could say that. The answer that lands names a constraint from your project and the thing you gave up to satisfy it. The shape is: the dashboard re-renders on every websocket message, so I wanted a diffing render layer instead of hand-written DOM updates, and the cost is a client bundle and a build step that a server-rendered template would not need. If you cannot name what a choice cost you, you did not make the choice.
2. Why this database?
They are asking whether you understand the shape of your data. Count your joins. If your Mongo code has three lookup stages, you have rebuilt a relational database badly, and the examiner can see it on the screen. If you did pick Mongo from a tutorial, do not defend it with "schema-less is flexible". Say: my access patterns turned out to be relational, here are the three aggregations that prove it, and I would use Postgres next time. That answer costs you nothing and buys you credibility for the rest of the viva.
3. What happens when ten thousand users hit this at the same time?
Do not say "I would add load balancing and caching". That is a sentence, not an answer. Almost every project has one thing that breaks first, and you can usually find it before the viva. Often it is a query inside a loop, a model running inference on the request thread, or an upload written to local disk so the app can never run on two machines. The shape is: the feed endpoint fetches the author for each of fifty posts, so one page is fifty-one queries, and I exhaust the connection pool long before I run out of CPU. The fix is a join, then an index, and only then a cache.
4. Show me where that happens in the code.
This question can be attached to anything you just said, and it is the one that separates the two kinds of student. Prepare by tracing one request end to end, out loud: route, middleware, controller, service, query, response. Know your entry point. Know the three files that actually matter. Have the go-to-symbol shortcut in your fingers. If you claimed something in your report, be able to open the file where it is true. Fifteen seconds of scrolling and silence will undo ten minutes of good answers.
5. Break it for me. Where does it fail?
Have a failure ready to perform. Submit an empty form, upload a file that is too large, stop the database and refresh the page. Then narrate the mechanism: the upload returns 413 because I cap the body at 10MB; with the database down the API returns a 503 with a JSON error body instead of a stack trace, because the connection error is caught in the error middleware, and /healthz reports unhealthy so a load balancer would pull the instance out of rotation; the form shows a field-level error because validation lives in the schema, not the handler. If your project does not fail gracefully, say so honestly and say what you would add. A student who has watched their own project break knows strictly more than one who has only watched it work.
6. Your model is 96% accurate. Is that good?
Probably not, and the answer depends on the base rate. If 96% of your rows are the negative class, a model that predicts "no" every single time also scores 96%. Report precision and recall for the minority class, show the confusion matrix, and name the baseline you beat. Then say which error is expensive: in disease screening a false negative is the one that hurts, so I moved the threshold down and accepted more false positives. And be ready for the leakage question, because it is coming: did you fit the scaler or the vectoriser before or after the split? Fitting it on the full dataset before the split is one of the most common ways a student project earns a number it did not earn. Duplicate rows landing on both sides of the split, and a feature that quietly encodes the target, are the other two.
7. How is this different from what already exists?
The trap is claiming novelty you do not have. "There is nothing like this" is false for nearly every student project, and the examiner knows the literature better than you do. The strong answer is a scoped, honest delta: existing tools do A and B, mine does B for a context they do not cover, and the part that is genuinely mine is the pipeline in the middle. Bounding your claim is not weakness. An examiner who catches you overclaiming once will spend the rest of the viva testing everything else you said.
8. Which parts of this did you write yourself?
Ask yourself this first, file by file, before someone else does. Nobody expects you to have written the ORM, the auth library or the charting code, and using an AI assistant is not the crime. Not knowing what it produced is. The answer that works is boring and specific: the schema, the matching logic in this service and the retry logic here are mine; the auth middleware started from the framework's example and I changed the token lifetime; the UI components come from a library. Then be able to defend every line you just claimed.
9. What is the limitation of your project?
This is a gift, and students throw it away by getting defensive or by offering a fake limitation like "the UI could be prettier". Name a real one in engineering terms, with the reason it exists and the cost of fixing it. The shape is: the recommender is trained on a few thousand ratings from a few hundred users, so it can say nothing useful about a brand-new user, which is a cold start problem; I fall back to popularity, which is honest but not personalised; fixing it properly needs content-based features on the item side and metadata I do not have. Three sentences that show you know the boundary of your own work. The limitation you name yourself is a finding. The limitation the examiner finds is a hole.
10. What was the hardest bug you fixed?
This one is hard to fake, because the follow-up is always show me the commit. Have one ready, know its hash, and tell it as a story with a mechanism in it: the symptom, what you believed was happening, how you found out you were wrong, and what was actually causing it. "Uploads worked locally and failed in production because the container filesystem was read-only and I was writing temp files into the working directory" is a real answer, and git log --oneline followed by git show on the fix will back it up in five seconds. "There were many bugs and I solved them all" is an admission that you did not build it.
11. How did you test this?
If the honest answer is that you clicked around, say that, and then say what you would test first and why. Better: know your riskiest function and have one test sitting on it. The examiner is not counting tests. They are checking whether you know which part of your own system you do not trust. Saying "the date-range filter is the piece I am least sure of, because timezone handling crosses three layers" scores higher than any coverage percentage.
12. What would you do differently if you started again?
Have three answers, ranked, and make at least one of them architectural rather than cosmetic. "I would use TypeScript" is fine but small. "I would put file processing behind a queue instead of doing it inside the request, because that one decision is the reason I cannot scale the API horizontally" is an engineer's answer. This is the question where the examiner decides whether you learned anything. Never say "nothing, I am happy with it".
Rehearse by having someone open a random file and ask what it does
Three days before the viva, hand your laptop to a friend or a labmate with two rules. They pick the file, not you. And they are allowed to ask "why is this here" twice in a row. Anything you cannot explain in two sentences goes on a list. Most of that list you simply learn. Some of it is dead code left over from an earlier approach, and "that was a leftover, so I removed it" is a legitimate and even good answer - as long as you remove it safely, which is not what a panicking student does the night before.
Underneath all twelve questions there is one question. The examiner is not asking you to defend the project. They are asking whether there is an engineer attached to it. A small project with a known bottleneck, a named failure mode, an honest limitation and a rejected alternative behind every choice reads as engineered. A large project whose author cannot say why the database is what it is does not. We think a project you can defend is a side effect of a project that was actually engineered - which is why, when we build with students at Tenzok, the decision log belongs beside the code, not in an appendix written the week before the viva.
Frequently asked