Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Groovy (Jenkins, Gradle and Spock) Module 2

Core syntax: values, strings, operators and control flow interview questions

Interview questions on “Core syntax: values, strings, operators and control flow”: warm-ups, then what each harder question tests and how a good answer starts.

18 questions: 6 warm-ups and 12 with model answers · Levels: Fresher to senior

Warm-up questions

Short questions with short answers, each answered in full.

  1. Fresher to mid

    Why is 1 / 2 equal to 0.5 in Groovy, and how do you get Java's integer division?

    Answered in the lesson Numbers, variables, def, var and val

  2. Fresher to mid

    What is the difference between 'Hi ${name}' and "Hi ${name}" in Groovy?

    Answered in the lesson Strings, GStrings and multi-line text

  3. Fresher to mid

    What does the Elvis operator do in Groovy, and when is it the wrong choice?

    Answered in the lesson Groovy truth, null safety and the Elvis operator

  4. Fresher to mid

    What does the spread operator *. do in Groovy, and what does it give for a null list?

    Answered in the lesson Operators, ranges, spread and membership

  5. Fresher to mid

    How does Groovy's switch decide that a case matches?

    Answered in the lesson Control flow, loops and the Groovy switch

  6. Fresher to mid

    What is the difference between =~ and ==~ in Groovy?

    Answered in the lesson Regular expressions the Groovy way

Questions with model answers

What each question tests, the first step of a good answer and the follow-ups to expect.

  1. Mid to senior

    A Groovy job reads invoice amounts such as 19.99 from a CSV, converts each with toDouble() and stores whole cents with (amount * 100) as long. Some invoices come out one cent short. Explain the cause, fix the conversion, and say how you would test the fix.

    What it tests
    Binary floating point against BigDecimal, truncating conversions, exact conversion with longValueExact(), and test values that expose the loss.
    First step
    Reproduce it with one value. As a double, 19.99 times 100 is 1998.9999999999998, and as long cuts the fraction off, giving 1998. The double never held 19.99 exactly, so the fix starts where the text is parsed: read it with toBigDecimal() instead of toDouble().
    Follow-ups

    From the lesson Numbers, variables, def, var and val

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.

    Opening the model answers with your pass…

    Model answers open with any MySmartCoPilot pass.

    • Pro pass · 1 week₹79$2.99
    • 30 days₹179$5.99
    • 1 year₹1,699$45

    One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

    It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  2. Mid to senior

    A shared library rounds build durations with seconds.round(), where seconds is a BigDecimal. Its tests pass on Groovy 5.1.3, but in Jenkins the same call fails with NullPointerException: Cannot read field "precision". Explain why, and give a fix that behaves the same in both places.

    What it tests
    Knowing which Groovy each environment runs, that GDK methods appear in particular versions, and preferring Java API calls whose behaviour does not change.
    First step
    Ask which Groovy runs in each place: the tests use 5.1.3, while Jenkins 2.580.1 bundles groovy-all 2.4.21. The GDK lists BigDecimal.round() only since Groovy 2.5.0, so on 2.4.21 the call reaches Java's own round(MathContext) without a MathContext, and that method fails on the missing argument.
    Follow-ups

    From the lesson Numbers, variables, def, var and val

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  3. Fresher to mid

    A deployment script builds a map of image tags with keys written "${service}-${env}". Printing the map shows api-prod, but tags['api-prod'] returns null. Explain the cause, give two fixes, and say how a test would have caught it.

    What it tests
    The difference between Groovy's == and Java's equals and hashCode, GString keys in collections, and writing a test that looks keys up the way callers do.
    First step
    Print the class of a key: tags.keySet()[0].getClass() shows GStringImpl, not String. A hash map finds keys by hashCode and equals, and a GString and a String with the same text differ in both, so the String lookup misses even though the printed map looks right.
    Follow-ups

    From the lesson Strings, GStrings and multi-line text

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  4. Mid to senior

    Reading a colleague's Jenkinsfile, you see sh "deploy --token ${env.DEPLOY_TOKEN} --target ${params.TARGET}". What two problems does it have, how do you rewrite it, and how would you show that the rewrite fixes them?

    What it tests
    Knowing that Pipeline interpolates like Groovy, the exposure of secrets in command text, injection through parameters, and quoting for the shell.
    First step
    Notice the double quotes: the argument is a GString, so Groovy puts the token and the target into the command text before the shell starts. That exposes the token in the process arguments, and any ; or $ in TARGET becomes shell syntax. The fix keeps both values out of the text.
    Follow-ups

    From the lesson Strings, GStrings and multi-line text

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  5. Fresher to mid

    A pipeline step runs if (env.SKIP_TESTS) { echo 'Skipping tests' } else { runTests() }. A job sets SKIP_TESTS to the text false, and the tests are still skipped. Explain why, fix the check, and say how you would make every flag of the shared library behave the same way.

    What it tests
    Groovy truth for text, converting flags with toBoolean(), the difference between a missing and a false flag, and putting one rule in one helper.
    First step
    An environment value is always text, and text is true whenever it is not empty. 'false' has five characters, so the condition is true and the tests are skipped. The fix converts the text before it is tested, for example with env.SKIP_TESTS?.toBoolean().
    Follow-ups

    From the lesson Groovy truth, null safety and the Elvis operator

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  6. Mid to senior

    A deploy helper reads int retries = config.retries ?: 3. A team sets retries to 0 to stop retrying a step that is not safe to repeat, and the step still runs three times. Explain the cause, write a fix that also compiles in a Jenkinsfile, and say how you would test it.

    What it tests
    The Elvis operator and Groovy truth, null checks for defaults, which syntax Groovy 2.4.21 accepts, and choosing test cases from the values that truth treats specially.
    First step
    The Elvis operator uses Groovy truth, and 0 is false, so config.retries ?: 3 gives 3 for a deliberate 0 exactly as for a missing value. The default has to be chosen by comparing with null instead.
    Follow-ups

    From the lesson Groovy truth, null safety and the Elvis operator

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  7. Mid to senior

    A release script treats a feature as on with if ('dryRun' in options), where options = [dryRun: false] means off. It behaved on Groovy 5.1.3, but after the move to 6.0.0 every release runs as a dry run. Explain the change, write a check that means the same everywhere, and say how you would find other affected lines.

    What it tests
    How in changed between Groovy 5 and 6, the difference between a key test and a value test, and searching code for a construct whose meaning changed.
    First step
    Ask which question the line asks on each runtime. On 5.1.3, in calls the map's isCase, which tests the value's truth, so false meant off. Groovy 6.0.0 compiles in to isIn, which tests the key, and the key dryRun exists, so the check is now true.
    Follow-ups

    From the lesson Operators, ranges, spread and membership

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  8. Mid to senior

    Design a Money type for Groovy scripts so that totals read as a + b, comparisons as a < b and lists of amounts add up with sum(). Which methods do you write, what must equals and hashCode do, and what should happen when two currencies meet?

    What it tests
    Operator overloading by method names, Comparable and equality contracts, behaviour of sum() and +=, and making invalid combinations fail.
    First step
    Store the amount exactly, as a long count of the smallest unit with a currency code, then map each operator to its method: plus and minus for + and -, multiply for * by a whole number, compareTo for < and >, with equals and hashCode consistent with compareTo.
    Follow-ups

    From the lesson Operators, ranges, spread and membership

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  9. Mid to senior

    A helper builds deploy closures in for (service in services) { jobs[service] = { deploy(service) } } and runs them later. In a Groovy 6.0.0 script every service is deployed; on Groovy 5.1.3 and on the groovy-all 2.4.21 jar, the last service is deployed three times. Explain why and give a fix that works everywhere.

    What it tests
    How closures capture variables, the Groovy 6 change to for-in loop variables, and writing loop code whose meaning does not depend on the runtime.
    First step
    A closure keeps the variable it uses, not its value. Before Groovy 6 a for-in loop has one variable for all its passes, so every closure reads the last service when it finally runs; Groovy 6 gives each pass a fresh variable (GROOVY-11792), so the same code works there.
    Follow-ups

    From the lesson Control flow, loops and the Groovy switch

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  10. Mid to senior

    A report tool maps build results with def colour = switch (result) { case 'SUCCESS' -> 'green'; case 'FAILURE' -> 'red' }. It runs on Groovy 4.0.33 in one place and 6.0.0 in another. A new result, NOT_BUILT, appears. What does each runtime do, and how do you make the code safe for new values?

    What it tests
    Switch expressions, the Groovy 6 change for unmatched values, defensive defaults, and tests for values the code does not know yet.
    First step
    The switch's value is assigned, so it is a switch expression. On Groovy 6.0.0 an expression that no arm covers throws IllegalStateException; Groovy 4.0.33 compiled the expression into a closure that silently returned null, so the colour there is null and the problem shows up later.
    Follow-ups

    From the lesson Control flow, loops and the Groovy switch

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  11. Mid to senior

    A scripted Pipeline does def m = readFile('build.log') =~ /app:(\S+)/, then runs sh 'make deploy', and afterwards uses m[0][1]. The build fails with java.io.NotSerializableException: java.util.regex.Matcher. Explain the cause and give two fixes.

    What it tests
    How Jenkins saves a running Pipeline, which objects can be serialized, and the two ways out: extracting plain values and @NonCPS helpers, with their limits.
    First step
    Jenkins keeps a Pipeline resumable by serializing its running state, and local variables are part of that state. m holds a java.util.regex.Matcher, which is not Serializable, so saving the state while the step runs fails. Keep only the String the Matcher found.
    Follow-ups

    From the lesson Regular expressions the Groovy way

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes
  12. Fresher to mid

    Write the approach for a helper that returns the highest release tag from a list such as v1.9.0, v1.10.0, v2.0.0-rc1 and release-1.2, ignoring pre-releases and names that are not versions. Which pattern do you use, how do you compare, and which cases do you test?

    What it tests
    Validating a whole value with ==~, extracting groups portably, numeric against text comparison, and choosing test cases from the traps.
    First step
    Accept only names that match the whole pattern v(\d+)\.(\d+)\.(\d+) with ==~, so v2.0.0-rc1 and release-1.2 are left out. Then compare the three numbers as integers, because as text v1.9.0 sorts after v1.10.0.
    Follow-ups

    From the lesson Regular expressions the Groovy way

    Model answer, Pro.

    In the answer:

    • Model answer
    • Follow-up answers
    • Common mistakes
    • Rubric
    • Variants
    • about 3 minutes

All Groovy (Jenkins, Gradle and Spock) interview questions · The Groovy (Jenkins, Gradle and Spock) track

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.