TL;DR: A quality gate is a pass/fail condition on code metrics that a pipeline enforces. Set it on new code only (coverage, duplication, issues on the lines this change touched) rather than on the whole project, or an existing codebase fails from day one and the gate gets disabled within a month.
How to approach it
Explain what the gate measures, then go straight to the adoption problem, because that is the real question behind this one. Anybody can install SonarQube. Making it a check developers respect rather than a step they route around is the part that takes judgement, and the new-code framing is the whole answer.
A strong answer
A quality gate is a set of conditions evaluated after analysis, producing one pass or fail. Typical conditions: coverage on new code above 80 percent, no new issues above a severity, duplication on new code below 3 percent, and no new security hotspots left unreviewed. The pipeline calls the analysis, waits for the result, and fails the build if the gate failed.
What the analysis actually reports is worth separating, because the categories carry different weight. Bugs are patterns likely to be wrong at runtime, like a possible null dereference. Vulnerabilities are security-relevant patterns. Code smells are maintainability problems, which are the bulk of the count and the least urgent. Coverage comes from your own test run, imported rather than measured by the analyser, which surprises people: if the pipeline does not produce a coverage report, Sonar reports zero and the gate fails for a reason that has nothing to do with code quality.
Now the part that decides whether this works. Point a tool like this at a codebase with eight years of history and it will report several thousand issues and 30 percent coverage. Gate on the overall numbers and every build fails immediately, through no fault of the person who opened the pull request. What happens next is predictable: the threshold gets lowered, then the gate gets marked non-blocking, then nobody looks at it.
Gating on new code avoids all of that. The condition applies only to lines added or changed in this pull request. Existing debt is reported and not blocking. A developer touching twenty lines needs those twenty lines covered and clean, which is achievable in the same sitting. The codebase improves wherever it is actively worked on, which is where it matters, and the old code nobody touches stays as it is until somebody does.
Two implementation details that make it usable. Analyse the pull request rather than the branch, so results appear as a comment or a check on the pull request itself rather than on a dashboard nobody opens. And let the developer see which specific lines failed, since a gate that says "coverage 71 percent" with no location is a scavenger hunt.
On what should block: the gate blocks merge, not deploy. Catching it at the merge is the cheap moment. Adding it as a release gate repeats the same mistake as security scanning, where the finding arrives when it is most expensive to act on.
What interviewers probe next
"How do you handle legitimate exceptions?" Suppress in code with a comment giving the reason, so it is reviewed in the pull request like anything else, rather than in the server's UI where it is invisible to reviewers.
"Does coverage percentage measure quality?" No. It measures which lines executed during tests, not whether anything was asserted. It is a useful floor and a terrible target, and a team optimising the number will write tests with no assertions.
"Where does this sit against SAST?" Overlapping. SonarQube's security rules are a form of SAST, and a dedicated tool goes deeper. Running both is common, and the thing to avoid is two tools reporting the same finding into two different places.
Common mistakes
Gating on whole-project metrics on an existing codebase, which fails everything and ends with the gate disabled.
Not publishing a coverage report from the test step, so the gate fails on zero coverage and people conclude the tool is broken.
Treating code smells with the same urgency as vulnerabilities, which floods the signal.
Putting the gate at the release step rather than the merge, so the feedback lands weeks after the code was written.