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.

Data Formats (JSON, YAML, TOML, XML, CSV) Module 4

Querying JSON: JSONPath, jq, JMESPath and SQL interview questions

Interview questions on “Querying JSON: JSONPath, jq, JMESPath and SQL”: warm-ups, then what each harder question tests and how a good answer starts.

10 questions: 3 warm-ups and 7 with model answers · Levels: Fresher to senior

Warm-up questions

Short questions with short answers, each answered in full.

  1. Fresher to mid

    What does a JSONPath query return when nothing matches, and how do you tell that from a match whose value is null?

    Answered in the lesson JSONPath (RFC 9535): selectors and segments

  2. Fresher to mid

    Why does $.items[?@.discount == null] miss the items that have no discount member?

    Answered in the lesson JSONPath filters, comparisons and functions

  3. Fresher to mid

    jq, JMESPath or JSONPath: which can group orders by city and total them, and which can only select?

    Answered in the lesson jq, JMESPath and SQL JSON paths compared

Questions with model answers

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

  1. Fresher to mid

    A nightly job totals the values of $..price_paise in each partner's catalogue. One partner starts listing gift cards, and its total rises by exactly the gift cards' prices, with no error anywhere. Explain why, and how you would change the query and the job so that the next new kind of priced item cannot change a total unnoticed.

    What it tests
    Knowing that a descendant segment matches a name at every depth, writing explicit paths instead, and adding checks on normalized paths or a schema that flag new structures.
    First step
    Print the normalized path of every node the query returned. $..price_paise gave $['gift_cards'][0]['price_paise'] beside the four book prices, because .. applies the name selector to every node below the root. Total $.books[*].price_paise, the place you mean, and report any price that $..price_paise finds outside it.
    Follow-ups

    From the lesson JSONPath (RFC 9535): selectors and segments

    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 contract test compares the nodelist of $.stock.* from a Python service with the one a Node.js service returns for the same document. The values always match as a set, but the test fails when stock is keyed by PIN codes such as 560001 and passes when it is keyed by city names. Explain the failure and fix the test.

    What it tests
    Knowing that RFC 9535 leaves the order of object members open, that JavaScript lists integer-like keys first, and comparing nodelists by normalized path instead of by position.
    First step
    Print both nodelists with their normalized paths and line them up. Python returned $['stock']['560001'] before $['stock']['411001'], in the document's order, while the Node.js service returned 411001 first; with city names both kept the document's order. Before you call either service wrong, read what section 2.3.2 of RFC 9535 says about the order of an object's members, and how JSON.parse orders keys that look like integers.
    Follow-ups

    From the lesson JSONPath (RFC 9535): selectors and segments

    Model answer, Pro.

    In the answer:

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

    A rules engine lets customers write JSONPath filters that route their orders, and its library evaluates filter text as JavaScript. Security asks you to move to an RFC 9535 library without breaking any customer's routing. How do you plan and prove the move?

    What it tests
    Seeing that evaluated filters are code injection, knowing where script-style filters and RFC 9535 differ, and migrating with a parser check, side-by-side runs and limits.
    First step
    Stop the risk before the migration: put every stored filter through an RFC 9535 parser today and list the ones it refuses, such as script expressions like [(@.length-1)] and JavaScript operators like === or .includes(). Those filters are the ones that cannot simply move; the rest can run on both libraries side by side.
    Follow-ups

    From the lesson JSONPath filters, comparisons and functions

    Model answer, Pro.

    In the answer:

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

    The filter $.addresses[?match(@.pin, '[0-9]{6}')] keeps six-digit postal codes. A Python port written as re.match(r'\d{6}', pin) also accepts 5600012 and ५६०००१, codes the filter drops. Explain both acceptances and fix the port so that it agrees with the filter.

    What it tests
    Knowing that match() tests the whole string, that re.match anchors only at the start, that Python's \d matches any Unicode digit, and how to translate I-Regexp into Python.
    First step
    Run the old and the new check on both codes. re.match found 560001 at the start of 5600012 and stopped, because it anchors only at the start, while match() in JSONPath tests the whole string, as re.fullmatch does. And Python's \d matches every Unicode decimal digit, Devanagari ones included, while the filter's [0-9] means 0 to 9 only.
    Follow-ups

    From the lesson JSONPath filters, comparisons and functions

    Model answer, Pro.

    In the answer:

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

    A deploy script picks one running server with aws ec2 describe-instances --output text and the query "Reservations[].Instances[?State.Name == 'running'].InstanceId | [0]". In a large account it sometimes prints several ids, and the next step breaks. Explain why, and make it print exactly one id every time.

    What it tests
    Reading JMESPath projections and pipes, knowing that the AWS CLI runs --query once per page with text output, and choosing output and filters that give one value.
    First step
    Run the expression on saved output first. Without a flatten, the projection gives one list per reservation, so | [0] returns the first reservation's list, which can hold several ids. Then read the AWS CLI guide: with --output text the query runs once on each page of results, so even a correct | [0] prints one id per page.
    Follow-ups

    From the lesson jq, JMESPath and SQL JSON paths compared

    Model answer, Pro.

    In the answer:

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

    A jq step adds a computed total to each record of a ledger and passes every other member through. Downstream, the 20-digit record ids still match, but the totals of very large counters are wrong in their last digits. Why does jq keep one number exactly and not the other, and how do you make the pipeline safe?

    What it tests
    Knowing that jq 1.8 keeps the text of unchanged number literals but computes in double precision, and choosing ids as strings and exact arithmetic for large totals.
    First step
    Run both cases through jq: an unchanged literal such as 12345678901234567890 came out exactly, while .ref + 0 printed 12345678901234567000. jq keeps a number's original text only until it computes with it, and arithmetic is done in IEEE 754 double precision, exact for integers up to 2^53 − 1 only.
    Follow-ups

    From the lesson jq, JMESPath and SQL JSON paths compared

    Model answer, Pro.

    In the answer:

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

    A report joins a table of branches to orders stored as JSON in SQLite with ON b.city = o.doc -> '$.city', and it matches no rows, although every city is in both tables. Explain the empty result, fix the join, and say which other comparisons in the report are at risk.

    What it tests
    Knowing that -> returns JSON text and ->> an SQL value, and checking types in joins, filters and sums over JSON columns.
    First step
    Select both sides next to each other: doc -> '$.city' gave "Pune", with the JSON quotes, while the branches table holds Pune, so no pair is equal. ->> returns the SQL text Pune. Change the join to b.city = o.doc ->> '$.city'.
    Follow-ups

    From the lesson jq, JMESPath and SQL JSON paths compared

    Model answer, Pro.

    In the answer:

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

All Data Formats (JSON, YAML, TOML, XML, CSV) interview questions · The Data Formats (JSON, YAML, TOML, XML, CSV) 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.