Skip to content

Instantly share code, notes, and snippets.

@thomasht86
Created October 18, 2025 08:08
Show Gist options
  • Select an option

  • Save thomasht86/71fceac729b4a62852ad956399f2f49e to your computer and use it in GitHub Desktop.

Select an option

Save thomasht86/71fceac729b4a62852ad956399f2f49e to your computer and use it in GitHub Desktop.
Vespa Quiz
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "textual",
# ]
# ///
# -*- coding: utf-8 -*-
"""
Terminal Quiz Application using Textual
"""
import json
import sys
from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, Static, ListView, ListItem, ProgressBar
from textual.binding import Binding
# Sample quiz JSON data (based on Vespa.ai documentation)
quiz_data_json = """
{
"title": "Vespa Documentation Quiz",
"description": "Test your knowledge of Vespa.ai – the open-source AI search platform!",
"questions": [
{
"question": "What is the primary function of Vespa?",
"options": [
"A scalable engine for low-latency computation over large data sets.",
"A distributed file system for long-term archival.",
"A framework for building user interfaces.",
"A relational database management system."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/overview.html",
"explanation": "Vespa is a powerful and scalable engine for low-latency computation over large data sets, designed for real-time applications.",
"difficulty": 1,
"topic": "Core Concepts"
},
{
"question": "Which of the following is NOT a key feature of Vespa?",
"options": [
"Real-time Indexing and Search",
"Approximate Nearest Neighbor (ANN) Search",
"Batch processing of historical data with high latency.",
"Flexible Ranking and Relevance"
],
"answer": 2,
"link": "https://docs.vespa.ai/en/overview.html",
"explanation": "Vespa is designed for low-latency, real-time applications, not high-latency batch processing.",
"difficulty": 2,
"topic": "Core Concepts"
},
{
"question": "What are the two main types of clusters in a Vespa application?",
"options": [
"Stateless Container Clusters and Stateful Content Clusters",
"Processing Clusters and Storage Clusters",
"Query Clusters and Indexing Clusters",
"Master Clusters and Worker Clusters"
],
"answer": 0,
"link": "https://docs.vespa.ai/en/overview.html",
"explanation": "A Vespa application consists of Stateless Container Clusters for handling requests and Stateful Content Clusters for storing and searching data.",
"difficulty": 2,
"topic": "Architecture"
},
{
"question": "What is the purpose of the `services.xml` file in a Vespa application package?",
"options": [
"To define the services and clusters of the application.",
"To specify the application's dependencies.",
"To configure the ranking and relevance models.",
"To define the document schemas."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/application-packages.html",
"explanation": "`services.xml` defines the services and clusters that make up the application, including their topology and resource allocation.",
"difficulty": 2,
"topic": "Application Packages"
},
{
"question": "What format is the Vespa access log in?",
"options": [
"JSON",
"A proprietary binary format",
"CSV",
"XML"
],
"answer": 0,
"link": "https://docs.vespa.ai/en/access-logging.html",
"explanation": "The Vespa access log format is JSON-based, allowing it to be processed by a number of available tools.",
"difficulty": 1,
"topic": "Access Logging"
},
{
"question": "How do you start all Vespa services on a node?",
"options": [
"$VESPA_HOME/bin/vespa-start-services",
"$VESPA_HOME/bin/start-services",
"sudo systemctl start vespa",
"sudo service vespa start"
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations-selfhosted/admin-procedures.html",
"explanation": "You can start all Vespa services on a node using the `$VESPA_HOME/bin/vespa-start-services` command.",
"difficulty": 2,
"topic": "Operations"
},
{
"question": "Which API is recommended for high-performance feeding of data into Vespa?",
"options": [
"Feeding API (vespa-feed-client)",
"Document API (/document/v1/)",
"A RESTful bulk document API",
"A gRPC-based streaming API"
],
"answer": 0,
"link": "https://docs.vespa.ai/en/api.html",
"explanation": "The Feeding API, accessed via `vespa-feed-client`, is the recommended API for high-performance data feeding.",
"difficulty": 3,
"topic": "APIs"
},
{
"question": "What is the purpose of an 'attribute' in a Vespa schema?",
"options": [
"To store fields in-memory for fast access during ranking, sorting, and grouping.",
"To specify a field's data type.",
"To define a field that should be indexed for full-text search.",
"To add metadata to a field, like a description or a display name."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/attributes.html",
"explanation": "Attributes are in-memory data structures that speed up query execution and document updates by trading off memory.",
"difficulty": 2,
"topic": "Data Modeling"
},
{
"question": "What is the default environment for manual deployments in Vespa Cloud?",
"options": [
"dev",
"prod",
"staging",
"test"
],
"answer": 0,
"link": "https://cloud.vespa.ai/en/developer-guide.html",
"explanation": "The `dev` environment is the default for manual deployments and is designed for rapid development cycles.",
"difficulty": 2,
"topic": "Vespa Cloud"
},
{
"question": "What is the purpose of 'autoscaling' in Vespa Cloud?",
"options": [
"To automatically adjust hardware resources based on actual usage.",
"To automatically adjust the number of document replicas based on traffic.",
"To automatically deploy new versions of the application when a new commit is pushed.",
"To automatically order pizza for the development team on Fridays."
],
"answer": 0,
"link": "https://cloud.vespa.ai/en/autoscaling.html",
"explanation": "Autoscaling in Vespa Cloud automatically adjusts the hardware resources allocated to application clusters depending on actual usage to optimize cost and performance.",
"difficulty": 2,
"topic": "Vespa Cloud"
},
{
"question": "How are documents mapped to buckets in Vespa?",
"options": [
"Algorithmically by their ID.",
"Based on the document's content.",
"Randomly at time of insertion.",
"Based on the current load of the content nodes."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/content/buckets.html",
"explanation": "The content layer splits the document space into chunks called buckets, and algorithmically maps documents to buckets by their ID.",
"difficulty": 3,
"topic": "Architecture"
},
{
"question": "What is the purpose of a 'searcher' component in Vespa?",
"options": [
"To process queries and their results.",
"To handle incoming document operations.",
"To manage the lifecycle of a query.",
"To perform background maintenance tasks."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/searcher-development.html",
"explanation": "Searchers are components that process Queries and their Results, allowing for custom logic to be applied to the search process.",
"difficulty": 2,
"topic": "Components"
},
{
"question": "What does the 'paged' attribute setting allow for?",
"options": [
"Paging attribute data out of memory to disk.",
"Loading only a subset of an attribute's values into memory at a time.",
"Paginating through the results of a query.",
"Paging the on-call engineer when something goes wrong."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/attributes.html#paged-attributes",
"explanation": "The 'paged' attribute setting allows paging attribute data out of memory to disk, which can be useful when there are memory resource constraints.",
"difficulty": 4,
"topic": "Performance & Tuning"
},
{
"question": "What is the role of the 'distributor' process in a content cluster?",
"options": [
"To calculate the correct content node for a document using the distribution algorithm.",
"To distribute queries to the content nodes.",
"To manage the cluster state and node health.",
"To perform maintenance operations like bucket splitting and joining."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/content/content-nodes.html#distributor",
"explanation": "The distributor calculates the correct content node using the distribution algorithm and the cluster state, and forwards document operations accordingly.",
"difficulty": 3,
"topic": "Architecture"
},
{
"question": "How can you debug a Java component running in a self-hosted Vespa container?",
"options": [
"By setting up a remote debugging configuration in an IDE and connecting to the JDWP agent.",
"By inspecting the container logs for stack traces and error messages.",
"By adding custom logging statements to the component code.",
"By asking the component nicely to tell you what's wrong."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/developer-guide.html#debugging-components",
"explanation": "You can debug a Java component by setting up a remote debugging configuration in your IDE and connecting to the JDWP agent enabled in the container's JVM options.",
"difficulty": 4,
"topic": "Development"
},
{
"question": "What is the purpose of the HNSW index in Vespa?",
"options": [
"To speed up approximate nearest neighbor searches.",
"To create a hierarchical index for faceted search.",
"To index documents in a way that is optimized for social network analysis.",
"To index hyperlinks in web pages."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/approximate-nn-hnsw.html",
"explanation": "Vespa implements a modified version of the Hierarchical Navigable Small World (HNSW) graph algorithm to speed up searches for nearest neighbors.",
"difficulty": 3,
"topic": "Indexing & Search"
},
{
"question": "What is the default query timeout in Vespa?",
"options": [
"500ms",
"100ms",
"1000ms",
"It depends on the complexity of the query."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/graceful-degradation.html",
"explanation": "The default timeout for a query in Vespa is 500 milliseconds.",
"difficulty": 3,
"topic": "Querying"
},
{
"question": "What happens when feed is blocked in a Vespa content cluster?",
"options": [
"External write operations are rejected to avoid saturating resource usage.",
"The cluster starts to buffer write operations in memory.",
"The cluster automatically scales up to handle the increased load.",
"The cluster sends a polite email asking you to stop feeding so much data."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations/feed-block.html",
"explanation": "A content cluster blocks external write operations when at least one content node has reached the resource limit of disk or memory to prevent resource exhaustion.",
"difficulty": 3,
"topic": "Operations"
},
{
"question": "What is the 'ideal state' in a Vespa content cluster?",
"options": [
"A state where all buckets are located according to the ideal state distribution algorithm.",
"A state where all nodes are perfectly balanced in terms of CPU and memory usage.",
"A state where the cluster is not performing any maintenance operations.",
"A theoretical state that can never be reached in practice."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/content/content-nodes.html#maintenance-operations",
"explanation": "A stable system has all buckets located per the ideal state algorithm. When no maintenance operations are needed, the cluster is said to be in the ideal state.",
"difficulty": 4,
"topic": "Architecture"
},
{
"question": "How can you achieve result diversity in Vespa?",
"options": [
"Using grouping, match-phase diversity, or collapsefield.",
"By using a custom searcher to re-rank the results.",
"By using a query that is more specific and less ambiguous.",
"By ensuring your documents are from a wide range of political ideologies."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/result-diversity.html",
"explanation": "Vespa offers several mechanisms to achieve result diversity, including grouping, match-phase diversity, and the collapsefield parameter.",
"difficulty": 4,
"topic": "Querying"
},
{
"question": "What is the purpose of a 'document processor' in Vespa?",
"options": [
"To read and modify document operations in a chain.",
"To validate incoming documents against the schema.",
"To enrich documents with additional data before indexing.",
"To check documents for spelling and grammar errors."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/document-processing.html",
"explanation": "Document processing is a framework to create chains of configurable components, that read and modify document operations.",
"difficulty": 2,
"topic": "Components"
},
{
"question": "What is the `vespa-logfmt` tool used for?",
"options": [
"To view and format the Vespa log.",
"To analyze the performance of your Vespa application.",
"To convert Vespa logs to a different format.",
"To create fancy log-shaped art."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations-selfhosted/vespa-cmdline-tools.html#vespa-logfmt",
"explanation": "`vespa-logfmt` is a command-line tool used to view the Vespa log in a formatted way.",
"difficulty": 2,
"topic": "Operations"
},
{
"question": "How does Vespa handle schema changes?",
"options": [
"Most changes can be applied live without restarts, but some may require re-indexing or restarts.",
"All schema changes require a full re-index of all documents.",
"Schema changes can only be applied by stopping the cluster and redeploying the application.",
"It automatically adapts the schema based on the documents you feed."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/schemas.html#schema-modifications",
"explanation": "Vespa is designed to handle most schema changes live. The documentation specifies which changes require re-indexing or restarts.",
"difficulty": 3,
"topic": "Data Modeling"
},
{
"question": "What is the purpose of 'phased ranking' in Vespa?",
"options": [
"To use a less expensive ranking function for the first phase, and a more expensive one for a smaller subset of documents in the second phase.",
"To rank documents in multiple stages, with each stage considering different aspects of the document.",
"To rank documents based on their 'phase' in the document lifecycle.",
"To slowly phase out old ranking functions."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/phased-ranking.html",
"explanation": "Phased ranking is a performance optimization technique where a computationally cheaper ranking function is used in the first phase to select a set of top candidates, which are then re-ranked with a more expensive function in a second phase.",
"difficulty": 4,
"topic": "Ranking"
},
{
"question": "What is the 'document summary' in Vespa?",
"options": [
"The information that is shown for each document in a query result.",
"A pre-computed summary of each document that is stored in the index.",
"A dynamic summary of each document that is generated at query time.",
"A summary of all the documents you have ever fed to Vespa."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/document-summaries.html",
"explanation": "A document summary is the information that is shown for each document in a query result. What information to include is determined by a document summary class.",
"difficulty": 2,
"topic": "Querying"
},
{
"question": "What is 'grouping' in Vespa?",
"options": [
"A feature to group query hits based on a custom expression and calculate aggregations over the groups.",
"A way to group documents into categories for faceted search.",
"A feature for grouping similar documents together in the search results.",
"A way to group documents into folders."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/grouping.html",
"explanation": "The Vespa grouping language is a list-processing language which describes how the query hits should be grouped, aggregated, and presented in result sets.",
"difficulty": 3,
"topic": "Querying"
},
{
"question": "What is the 'config-sentinel' process responsible for?",
"options": [
"Starting, stopping, and restarting Vespa services on a node.",
"Monitoring the health of the Vespa services on a node.",
"Distributing configuration to the Vespa services on a node.",
"Guarding the configuration files from unauthorized access."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations-selfhosted/config-sentinel.html",
"explanation": "The config sentinel starts and stops services - and restart failed services unless they are manually stopped.",
"difficulty": 3,
"topic": "Operations"
},
{
"question": "What is the purpose of the 'predicate' field type in Vespa?",
"options": [
"To store boolean expressions and evaluate them against query-time attributes.",
"To store and search for geographical data.",
"To store and search for time-series data.",
"To store and search for grammatical predicates."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/predicate-fields.html",
"explanation": "Predicate fields are used to store boolean expressions that can be efficiently evaluated against attributes provided at query time, enabling features like targeted advertising.",
"difficulty": 5,
"topic": "Data Modeling"
},
{
"question": "What is the difference between 'flat' and 'grouped' content distribution?",
"options": [
"Flat distribution distributes data over a single group of nodes, while grouped distribution creates multiple groups, each with a full copy of the data.",
"Flat distribution is for small clusters, while grouped distribution is for large clusters.",
"Flat distribution provides better write performance, while grouped distribution provides better read performance.",
"Flat distribution is for flat-earthers, while grouped distribution is for people who believe in a round earth."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/performance/sizing-search.html#data-distribution",
"explanation": "Flat distribution involves a single group of nodes, with data partitioned across them. Grouped distribution involves multiple groups, each holding a complete replica of the data, which is useful for scaling query throughput.",
"difficulty": 4,
"topic": "Architecture"
},
{
"question": "What is the purpose of the `vespa-fbench` tool?",
"options": [
"For HTTP performance testing and benchmarking of Vespa.",
"For functional testing of Vespa applications.",
"For debugging Vespa applications.",
"For playing French horn concertos."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations/tools.html#vespa-fbench",
"explanation": "`vespa-fbench` is a tool for HTTP performance testing and benchmarking, allowing you to measure the performance of your Vespa application under load.",
"difficulty": 3,
"topic": "Performance & Tuning"
},
{
"question": "What is the 'document meta store'?",
"options": [
"An in-memory data structure for all documents on a node, mapping document IDs to local IDs.",
"A persistent data store for document metadata.",
"A cache for frequently accessed documents.",
"A place where documents go to have an existential crisis."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/attributes.html#document-meta-store",
"explanation": "The document meta store is an in-memory data structure for all documents on a node. It is an implicit attribute and is compacted and flushed.",
"difficulty": 4,
"topic": "Architecture"
},
{
"question": "What does it mean for a document to be 'global' in Vespa?",
"options": [
"The document is replicated to all nodes in the content cluster.",
"The document is accessible from all container clusters.",
"The document is stored in a special, globally-distributed cluster.",
"The document has a very worldly and sophisticated taste."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/parent-child.html",
"explanation": "Global documents are distributed to all nodes in a content cluster, which is a prerequisite for using them as parent documents in a parent-child relationship.",
"difficulty": 4,
"topic": "Data Modeling"
},
{
"question": "What is the purpose of the 'validation-overrides.xml' file?",
"options": [
"To allow deployment of an application package even if it fails validation.",
"To specify custom validation rules for your application package.",
"To disable validation of your application package.",
"To validate your life choices."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/validation-overrides.html",
"explanation": "`validation-overrides.xml` allows you to override validation checks that would otherwise prevent the deployment of an application package with potentially destructive changes.",
"difficulty": 4,
"topic": "Application Packages"
},
{
"question": "What is 'streaming search' in Vespa?",
"options": [
"A search mode where selection is only supported on predefined groups of documents.",
"A search mode where documents are streamed to the client as they are found.",
"A search mode that is optimized for searching over streaming data.",
"Searching for documents while streaming your favorite TV show."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/streaming-search.html",
"explanation": "Streaming search is a mode where search/selection is only supported on predefined groups of documents (e.g. a user's documents). In this mode each node can store and serve billions of documents while maintaining low response times.",
"difficulty": 4,
"topic": "Indexing & Search"
},
{
"question": "What is the purpose of the 'linguistics' module in Vespa?",
"options": [
"To process text in queries and documents during indexing and searching.",
"To provide language detection capabilities.",
"To translate queries and documents between different languages.",
"To help Vespa write poetry."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/linguistics.html",
"explanation": "Vespa uses a linguistics module to process text in queries and documents, including tokenization, normalization, and stemming.",
"difficulty": 3,
"topic": "Text Search"
},
{
"question": "How can you implement a custom REST API in Vespa?",
"options": [
"By implementing a custom request handler.",
"By using a generic REST API component and configuring it in services.xml.",
"By deploying a separate web server to handle your API requests.",
"By using a magic wand."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/jdisc/developing-request-handlers.html",
"explanation": "You can implement a custom REST API by developing a custom request handler, which allows you to define arbitrary HTTP APIs.",
"difficulty": 3,
"topic": "Components"
},
{
"question": "What is the default behavior of deployments to the 'dev' environment in Vespa Cloud?",
"options": [
"They are auto-downscaled to one small node.",
"They are automatically deleted after 24 hours.",
"They have a lower level of redundancy than production environments.",
"They are reviewed by a team of highly-trained monkeys."
],
"answer": 0,
"link": "https://cloud.vespa.ai/en/developer-guide.html#auto-downsizing",
"explanation": "Deployments to 'dev' are downscaled to one small node by default to minimize cost and make development cycles speedy.",
"difficulty": 3,
"topic": "Vespa Cloud"
},
{
"question": "What is the `vespa-visit` tool used for?",
"options": [
"To iterate over and retrieve documents from a content cluster.",
"To check the health of a content cluster.",
"To re-index documents in a content cluster.",
"To see which documents are trending on social media."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/visiting.html",
"explanation": "`vespa-visit` is a command-line tool that allows you to iterate over and retrieve documents from a Vespa content cluster.",
"difficulty": 2,
"topic": "Operations"
},
{
"question": "What is the purpose of 'federation' in Vespa?",
"options": [
"To allow multiple sources of data to be combined into a common search service.",
"To create a distributed Vespa cluster that spans multiple data centers.",
"To connect multiple Vespa clusters together for high availability.",
"To federate your Vespa application with your social media accounts."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/federation.html",
"explanation": "Federation in Vespa allows multiple sources of data to be federated to a common search service, which can include both internal Vespa clusters and external services.",
"difficulty": 4,
"topic": "Querying"
},
{
"question": "What does the 'bolding' feature do in document summaries?",
"options": [
"It highlights the query terms in the summary text.",
"It makes the entire summary text bold.",
"It bolds the most important keywords in the summary text.",
"It adds a bold new flavor to the search results."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/document-summaries.html#dynamic-snippets",
"explanation": "Bolding is a feature that highlights the matched query terms within a dynamic summary, making it easier for users to see why a document was matched.",
"difficulty": 3,
"topic": "Querying"
},
{
"question": "What is the 'config proxy' process?",
"options": [
"A process on every Vespa node that proxies config requests between applications and the config server.",
"A proxy for accessing the Vespa Cloud APIs.",
"A proxy for routing queries to the correct container cluster.",
"A service that automatically configures your Vespa application for you."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations-selfhosted/config-proxy.html",
"explanation": "The config proxy runs on every Vespa node and acts as a proxy for config clients on the same machine, caching configuration data locally.",
"difficulty": 4,
"topic": "Operations"
},
{
"question": "What is the maximum document size in Vespa?",
"options": [
"128 MiB, configurable per content cluster.",
"1 GiB",
"It depends on the available memory and disk space.",
"There is no limit, you can feed it the entire internet."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/faq.html#what-limits-apply-to-document-size",
"explanation": "Vespa has a maximum document size of 128 MiB, which is configurable per content cluster in services.xml.",
"difficulty": 4,
"topic": "Documents"
},
{
"question": "How do you perform a partial update of a document?",
"options": [
"By sending a PUT request with an update operation for the specific field.",
"By sending a PATCH request with the updated fields.",
"By sending a POST request with the updated fields.",
"By whispering the changes to the Vespa cluster."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/partial-updates.html",
"explanation": "Partial updates are performed by sending a PUT request to the document's URL with a JSON body specifying the update operation for the field to be modified.",
"difficulty": 3,
"topic": "Writes"
},
{
"question": "What is a 'rank profile' in Vespa?",
"options": [
"A named set of ranking calculations that can be selected at query time.",
"A file that contains the ranking model for your application.",
"A component that is responsible for ranking documents.",
"A list of the top-ranking Vespa applications."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/ranking.html",
"explanation": "A rank profile is a named set of ranking calculations that determines how documents are scored for a given query. Different rank profiles can be selected at query time.",
"difficulty": 2,
"topic": "Ranking"
},
{
"question": "What does the 'fast-access' attribute setting do?",
"options": [
"It ensures that replicas of the attribute are always loaded in memory on all nodes.",
"It creates a special index for the attribute to speed up searches.",
"It caches the attribute in the container cluster for faster access.",
"It makes your queries run at the speed of light."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/attributes.html#fast-access",
"explanation": "The 'fast-access' attribute setting is used to increase feed rates by ensuring that replicas of the attribute are loaded in memory on all nodes with a replica.",
"difficulty": 4,
"topic": "Performance & Tuning"
},
{
"question": "What is the purpose of the 'Vespa Cloud Enclave'?",
"options": [
"It allows Vespa Cloud applications to run inside the tenant's own cloud accounts.",
"It provides a secure and isolated environment for running sensitive applications.",
"It allows you to connect your on-premise Vespa cluster to Vespa Cloud.",
"A witness protection program for Vespa documents."
],
"answer": 0,
"link": "https://cloud.vespa.ai/en/enclave/enclave.html",
"explanation": "Vespa Cloud Enclave allows Vespa Cloud applications to run inside the tenant's own cloud accounts, providing full access to Vespa Cloud features within their own cloud environment.",
"difficulty": 4,
"topic": "Vespa Cloud"
},
{
"question": "How are chained components executed in Vespa?",
"options": [
"Serially, based on ordering constraints.",
"In parallel, to improve performance.",
"In a random order, for chaos engineering purposes.",
"In a chain gang, with each component singing a sad song."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/components/chained-components.html",
"explanation": "Chained components are executed serially, and their order is determined by ordering constraints defined through annotations or configuration.",
"difficulty": 3,
"topic": "Components"
},
{
"question": "How do you specify a custom JVM heap size for a container cluster?",
"options": [
"Using the 'allocated-memory' attribute in the 'jvm' element within 'nodes' in services.xml.",
"By setting the `VESPA_JVM_ARGS` environment variable.",
"By passing the `-Xmx` and `-Xms` flags to the container's startup script.",
"By writing the desired heap size on a sticky note and attaching it to the server."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/performance/container-tuning.html#jvm-heap-size",
"explanation": "You can change the default JVM heap size by setting the 'allocated-memory' attribute in the 'jvm' element within the 'nodes' configuration in services.xml.",
"difficulty": 3,
"topic": "Performance & Tuning"
},
{
"question": "What is the 'config generation' in Vespa?",
"options": [
"A version number for the application's configuration, incremented on each deployment.",
"A snapshot of the application's configuration at a specific point in time.",
"A unique identifier for each configuration server in the cluster.",
"A conference for Vespa configuration enthusiasts."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations-selfhosted/configuration-server.html#status-and-config-generation",
"explanation": "A config generation is a version number that is incremented each time a new application package is deployed and activated.",
"difficulty": 3,
"topic": "Operations"
},
{
"question": "What happens when you add a new node to a content cluster?",
"options": [
"A new ideal state is calculated for all buckets, and some buckets are moved to the new node.",
"The new node automatically starts receiving a copy of all new documents.",
"You have to manually rebalance the data across the cluster.",
"The new node has to go through a rigorous initiation ritual."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/elasticity.html#adding-nodes",
"explanation": "When adding a new node, a new ideal state is calculated for all buckets. The buckets mapped to the new node are moved, and superfluous replicas are removed to maintain the configured redundancy.",
"difficulty": 3,
"topic": "Elasticity"
},
{
"question": "What is the 'weakAnd' query operator used for?",
"options": [
"To efficiently retrieve the top-k documents using an inner scoring function, as an alternative to AND and OR.",
"To perform a fuzzy search for documents that contain most of the query terms.",
"To find documents that contain at least one of the query terms, but with a lower score than OR.",
"For queries that are not very strong."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/using-wand-with-vespa.html",
"explanation": "The 'weakAnd' (WAND) operator is an optimized OR that efficiently finds the top-k documents by using an inner scoring function to discard irrelevant candidates early.",
"difficulty": 4,
"topic": "Querying"
},
{
"question": "What is the purpose of the `binarize` and `pack_bits` indexing converters?",
"options": [
"To map numbers in a vector to bits and represent them efficiently using the `int8` data type.",
"To convert text data to a binary format for faster indexing.",
"To compress the index to reduce its size on disk.",
"To pack your bits into a suitcase for a trip."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/binarizing-vectors.html",
"explanation": "The `binarize` and `pack_bits` converters are used to map numbers in a vector (embedding) to bits and represent the vector of bits efficiently using the `int8` data type, which is key to reducing memory requirements.",
"difficulty": 5,
"topic": "Advanced Features"
},
{
"question": "What is the purpose of the 'select' parameter in a query?",
"options": [
"To request specific multi-level result set statistics and/or hit groups to be returned in the result.",
"To select which document summary to use for the search results.",
"To specify which fields to return in the search results.",
"To select a new theme for the search results page."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/query-api-reference.html#select",
"explanation": "The 'select' parameter is used to request specific multi-level result set statistics and/or hit groups to be returned in the result, which is the interface to the grouping feature.",
"difficulty": 4,
"topic": "Grouping"
},
{
"question": "What is 'graceful query coverage degradation'?",
"options": [
"A mechanism to return a partial result set if a query cannot be completed within the timeout.",
"A feature that automatically retries a query if it fails.",
"A mechanism to reduce the scope of a query if it is too expensive.",
"A feature that makes your query results more polite."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/graceful-degradation.html",
"explanation": "Graceful query coverage degradation allows Vespa to return a partial result set if the query cannot be completed within the specified timeout, ensuring that the user still gets a response.",
"difficulty": 4,
"topic": "Performance & Tuning"
},
{
"question": "What is the purpose of the 'slobrok' process?",
"options": [
"Service location object broker, used for service discovery.",
"A load balancer for distributing queries across container clusters.",
"A message queue for communication between Vespa services.",
"A tool for creating slow-motion videos of your search results."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations-selfhosted/slobrok.html",
"explanation": "Slobrok stands for Service Location Object Broker and is used by some services in Vespa for service discovery.",
"difficulty": 5,
"topic": "Operations"
},
{
"question": "How do you define a parent-child relationship between document types?",
"options": [
"By using a 'reference' field in the child document to point to the parent document.",
"By nesting the child document within the parent document.",
"By using a special 'parent' field in the child document.",
"By creating a family tree of your documents."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/parent-child.html",
"explanation": "Parent-child relationships are defined by using a 'reference' field in the child document that points to the parent document. The parent document must be 'global'.",
"difficulty": 4,
"topic": "Data Modeling"
},
{
"question": "What is the `vespa-config-status` tool used for?",
"options": [
"To verify that all services on a node are running with updated config.",
"To check the status of the configuration servers.",
"To see the current configuration generation.",
"To get a status update on your Vespa's social life."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations-selfhosted/vespa-cmdline-tools.html#vespa-config-status",
"explanation": "`vespa-config-status` is a command-line tool used to verify that all services on a node are running with the latest updated configuration.",
"difficulty": 3,
"topic": "Operations"
},
{
"question": "What is a 'tensor' in Vespa?",
"options": [
"A multi-dimensional array used for representing data like vectors and matrices.",
"A data type for storing large binary objects.",
"A special field type for storing and searching for text.",
"A creature from a sci-fi movie that lives in your Vespa cluster."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/tensor-user-guide.html",
"explanation": "In Vespa, a tensor is a multi-dimensional array that can be used to represent various types of data, such as vectors for embeddings, matrices for machine learning models, and more.",
"difficulty": 2,
"topic": "Data Modeling"
},
{
"question": "What is the purpose of the `bm25` rank feature?",
"options": [
"To implement the Okapi BM25 ranking function for text relevance.",
"To calculate the term frequency-inverse document frequency (TF-IDF) of a document.",
"To measure the similarity between two documents.",
"To rank the 25 best beaches in the world."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/bm25.html",
"explanation": "The `bm25` rank feature implements the Okapi BM25 ranking function, a popular algorithm for estimating the relevance of a text document given a search query.",
"difficulty": 3,
"topic": "Ranking"
},
{
"question": "How can you run Vespa on a CPU older than Haswell (2013)?",
"options": [
"By using the generic x86 container image.",
"By compiling Vespa from source with the appropriate flags.",
"By using a virtual machine to emulate a newer CPU.",
"By giving your old CPU a pep talk and a cup of coffee."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/cpu-support.html",
"explanation": "For CPUs older than Haswell (2013), Vespa provides a generic x86 container image that is compiled for older CPUs, although it is slower and less frequently updated.",
"difficulty": 4,
"topic": "Operations"
},
{
"question": "What is the purpose of the 'reindexing' feature?",
"options": [
"To re-process documents through the indexing chain to apply changes to the schema or indexing logic.",
"To rebuild the index from scratch to improve performance.",
"To recover the index after a failure.",
"To play your favorite song on repeat."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations/reindexing.html",
"explanation": "Reindexing allows you to re-process documents through the indexing chain. This is necessary when you make certain changes to the schema or indexing logic that require the documents to be processed again.",
"difficulty": 3,
"topic": "Indexing & Search"
},
{
"question": "What is the purpose of the 'document selection language'?",
"options": [
"To select a subset of documents for feeding, dumping, and garbage collection.",
"To specify which documents to return in a search query.",
"To define the schema for your documents.",
"A secret language only Vespa developers understand."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/document-select-language.html",
"explanation": "The document selector language is used to define a text string format that can be parsed to build a parse tree, which in turn can answer whether a given document is contained within the subset or not.",
"difficulty": 4,
"topic": "Operations"
},
{
"question": "What is the `query-profile-dump-tool` used for?",
"options": [
"To dump all resolved query profile properties for a set of dimension values.",
"To export the query profiles to a file.",
"To import query profiles from a file.",
"To dump your query profile if it's not performing well."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations/tools.html#vespa-query-profile-dump-tool",
"explanation": "`vespa-query-profile-dump-tool` is a command-line tool that dumps all resolved query profile properties for a set of dimension values, which is useful for debugging query profiles.",
"difficulty": 5,
"topic": "Operations"
},
{
"question": "How can you monitor Vespa?",
"options": [
"Using the /state/v1/metrics API, Prometheus, and Grafana.",
"Using the Vespa Cloud console.",
"By enabling JMX and connecting to the container with a JMX client.",
"By asking the Vespa cluster how it's feeling today."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations-selfhosted/monitoring.html",
"explanation": "Vespa provides a metrics API at `/state/v1/metrics` and can be integrated with Prometheus and Grafana for monitoring and visualization.",
"difficulty": 3,
"topic": "Operations"
},
{
"question": "What is the `vespa-remove-index` tool used for?",
"options": [
"To completely wipe a content node of all data.",
"To remove the index for a specific document type.",
"To remove a specific field from the index.",
"To remove your Vespa application from the internet."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations-selfhosted/vespa-cmdline-tools.html#vespa-remove-index",
"explanation": "`vespa-remove-index` is a tool that can be used to completely wipe all data from a content node, which can be useful for starting over with a clean slate.",
"difficulty": 4,
"topic": "Operations"
},
{
"question": "What is the `sddocname` field in a search result?",
"options": [
"The name of the schema the document belongs to.",
"A unique identifier for the document within the search results.",
"The name of the content node that returned the document.",
"A really, really long and complicated name for the document."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/default-result-format.html#sddocname",
"explanation": "The `sddocname` field in a search result indicates the name of the schema (search definition) that the document belongs to.",
"difficulty": 3,
"topic": "Querying"
},
{
"question": "What is the difference between a 'put' and an 'update' operation?",
"options": [
"A 'put' operation replaces the entire document, while an 'update' operation modifies specific fields.",
"A 'put' operation is idempotent, while an 'update' operation is not.",
"A 'put' operation is faster than an 'update' operation.",
"There is no difference, they are the same thing."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reads-and-writes.html",
"explanation": "A 'put' operation will add a document or replace an existing document with the same ID. An 'update' operation, on the other hand, is used to modify one or more fields of an existing document without replacing the entire document.",
"difficulty": 2,
"topic": "Writes"
},
{
"question": "What is the purpose of the `match: word` setting for a string field?",
"options": [
"To treat the entire field content as a single token.",
"To perform a case-sensitive match.",
"To enable prefix matching.",
"To find the perfect match for your lonely string field."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/schema-reference.html#word",
"explanation": "The `match: word` setting tells Vespa to treat the entire content of a string field as a single token, which is useful for fields that should be matched exactly, like a UUID.",
"difficulty": 3,
"topic": "Text Search"
},
{
"question": "What is the `vespa-visit-target` tool used for?",
"options": [
"To act as a target for documents being visited, allowing for custom processing.",
"To specify which documents to visit.",
"To control the rate at which documents are visited.",
"To see which of your documents is the most popular."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations-selfhosted/vespa-cmdline-tools.html#vespa-visit-target",
"explanation": "`vespa-visit-target` is a tool that can act as a target for a visit session, allowing you to implement custom logic for processing the visited documents.",
"difficulty": 5,
"topic": "Operations"
},
{
"question": "What is the purpose of the `document id`?",
"options": [
"To uniquely identify a document within a Vespa installation.",
"To specify the namespace and user-specific ID of a document.",
"To group documents together.",
"A secret code that unlocks the true meaning of your documents."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/documents.html#document-ids",
"explanation": "The document identifier is a URI, represented by a string, which must conform to a defined URI scheme for document identifiers. It uniquely identifies a document within a Vespa installation.",
"difficulty": 1,
"topic": "Documents"
},
{
"question": "How do you enable BM25 ranking for a field?",
"options": [
"By adding `index: enable-bm25` to the field's indexing statement.",
"By setting the `ranking.bm25` property in the query.",
"By creating a rank profile that uses the `bm25` rank feature.",
"By writing a heartfelt letter to the Vespa team."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/bm25.html",
"explanation": "To enable BM25 ranking for a field, you must add `index: enable-bm25` to the field's indexing statement in the schema.",
"difficulty": 3,
"topic": "Ranking"
},
{
"question": "What is 'Vespa Enclave'?",
"options": [
"A feature that allows Vespa Cloud applications to run inside the tenant's own cloud accounts.",
"A secure sandbox for running untrusted code.",
"A dedicated hardware appliance for running Vespa.",
"A video game where you battle other Vespa users."
],
"answer": 0,
"link": "https://cloud.vespa.ai/en/enclave/enclave.html",
"explanation": "Vespa Cloud Enclave allows Vespa Cloud applications to run inside the tenant's own cloud accounts while everything is still fully managed by Vespa Cloud's automation.",
"difficulty": 4,
"topic": "Vespa Cloud"
},
{
"question": "What is the role of ZooKeeper in a Vespa configuration server cluster?",
"options": [
"It provides a distributed data storage for the configuration system.",
"It manages the election of the master configuration server.",
"It coordinates the deployment of application packages.",
"It manages the configuration of the zoo."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations-selfhosted/configuration-server.html#zookeeper",
"explanation": "A config server uses Apache ZooKeeper as a distributed data storage for the configuration system, handling data consistency across multiple config servers.",
"difficulty": 4,
"topic": "Operations"
},
{
"question": "What is the purpose of the 'feed block' mechanism?",
"options": [
"To prevent the content cluster from being overloaded by blocking external write operations when resource limits are reached.",
"To ensure that all replicas of a document are updated before acknowledging a write operation.",
"To prevent a single client from monopolizing the feeding bandwidth.",
"A special block of wood used to prop up the Vespa servers."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations/feed-block.html",
"explanation": "A content cluster blocks external write operations when at least one content node has reached the resource limit of disk or memory. This is done to avoid saturating resource usage on content nodes.",
"difficulty": 3,
"topic": "Operations"
},
{
"question": "What is a 'bucket' in Vespa's content layer?",
"options": [
"A chunk of the document space that documents are algorithmically mapped to by their ID.",
"A unit of data replication and distribution.",
"A logical partition of the content cluster.",
"A place where documents go to relax and unwind."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/content/buckets.html",
"explanation": "The content layer splits the document space into chunks called buckets, and algorithmically maps documents to buckets by their id.",
"difficulty": 3,
"topic": "Architecture"
},
{
"question": "What does the `vespa prepare` command do?",
"options": [
"Uploads and validates an application package on the config server, but does not activate it.",
"Prepares a new version of the application for deployment.",
"Checks the syntax of the application package files.",
"Prepares your Vespa application for its first day of school."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/application-packages.html#deploy",
"explanation": "The `vespa prepare` command uploads the application to the configuration server, validates it, and prepares it for activation, but does not make the new configuration active.",
"difficulty": 3,
"topic": "Deployment"
},
{
"question": "What does the `vespa activate` command do?",
"options": [
"Activates a previously prepared application package, making the new configuration live.",
"Starts the Vespa services on all nodes.",
"Enables the query and feeding endpoints for the application.",
"Activates your Vespa's hidden superpowers."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/application-packages.html#deploy",
"explanation": "The `vespa activate` command is issued after a successful `vespa prepare` to make the new configuration active, causing the config server cluster to switch to the new system model.",
"difficulty": 3,
"topic": "Deployment"
},
{
"question": "How can you implement custom logic for processing requests and responses in Vespa?",
"options": [
"By developing and deploying custom Java components like Searchers and Document Processors.",
"By using a scripting language like Python or JavaScript.",
"By configuring a set of built-in processing components.",
"By singing your logic to the servers."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/jdisc/container-components.html",
"explanation": "Vespa's container clusters host custom Java components (Searchers, Document Processors, etc.) that allow for extensive customization of query and data processing pipelines.",
"difficulty": 2,
"topic": "Components"
},
{
"question": "What is the purpose of the 'match-phase' feature?",
"options": [
"To limit the documents that are ranked in the first phase, based on an attribute, to improve performance.",
"To specify which fields to match against in the query.",
"To define a set of documents that should be considered for matching.",
"A feature that helps your documents find their soulmates."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/schema-reference.html#match-phase",
"explanation": "The 'match-phase' feature can be used to limit the documents that are exposed to first-phase ranking based on an attribute, which can significantly improve performance for queries that match many documents.",
"difficulty": 5,
"topic": "Performance & Tuning"
},
{
"question": "How do you specify which fields to return in a document summary?",
"options": [
"By defining a 'document-summary' in the schema and specifying the fields to include.",
"By using the 'summary' parameter in the query.",
"By default, all fields are returned in the summary.",
"By asking the document nicely to only show you the good parts."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/document-summaries.html",
"explanation": "Document summaries are defined in the schema using the 'document-summary' element, where you can specify which fields to include in the summary.",
"difficulty": 2,
"topic": "Querying"
},
{
"question": "What is the purpose of the 'grouping' feature in Vespa?",
"options": [
"To group and aggregate query hits based on custom expressions.",
"To group documents into clusters based on their similarity.",
"To group multiple queries together into a single request.",
"To group your developers into teams based on their favorite color."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/grouping.html",
"explanation": "The Vespa grouping language allows you to group query hits based on custom expressions and calculate aggregations over those groups, which is useful for features like faceting and creating navigational tools.",
"difficulty": 3,
"topic": "Querying"
},
{
"question": "What happens if a content node fails in a Vespa cluster with redundancy?",
"options": [
"The system automatically re-routes traffic and re-distributes data to maintain service.",
"The cluster enters a read-only mode until the node is restored.",
"Queries may return incomplete results until the node is restored.",
"The world ends."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/overview.html#architecture",
"explanation": "Vespa's architecture is designed for high availability and fault tolerance. When a node fails, the system automatically re-routes traffic and re-distributes data to maintain service and the configured redundancy level.",
"difficulty": 2,
"topic": "Architecture"
},
{
"question": "What is the primary benefit of using 'grouped distribution' for content clusters?",
"options": [
"To scale query throughput by dispatching queries to a single group at a time.",
"To improve data locality and reduce network traffic.",
"To increase the redundancy of the data.",
"To make your content clusters more sociable."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/elasticity.html#grouped-distribution",
"explanation": "Grouped distribution is useful for scaling query throughput, as Vespa will automatically send a query to just a single group, allowing for parallel query processing across groups.",
"difficulty": 4,
"topic": "Architecture"
},
{
"question": "How do you specify a conditional write operation?",
"options": [
"By adding a 'condition' parameter to the document operation with a document selection expression.",
"By using a special 'if-modified-since' header in the request.",
"By using a distributed lock to ensure that only one client can write to a document at a time.",
"By asking the document if it's okay to be updated."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/document-v1-api-guide.html#conditional-writes",
"explanation": "A test-and-set condition can be added to Put, Remove, and Update operations by specifying a 'condition' parameter with a document selection expression.",
"difficulty": 4,
"topic": "Writes"
},
{
"question": "What is the `proton` process responsible for?",
"options": [
"It is the search and storage engine running on content nodes.",
"It is the query processing engine running on container nodes.",
"It is the document processing engine running on container nodes.",
"It is the proton pack from Ghostbusters, but for data."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/proton.html",
"explanation": "Proton is the real-time search and storage engine that runs on each content node in a Vespa cluster.",
"difficulty": 3,
"topic": "Architecture"
},
{
"question": "What is the difference between a 'Searcher' and a 'Document Processor'?",
"options": [
"Searchers process queries and results, while Document Processors process incoming document operations.",
"Searchers run on container nodes, while Document Processors run on content nodes.",
"Searchers are written in Java, while Document Processors can be written in any language.",
"Searchers wear hats, while Document Processors wear glasses."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/jdisc/container-components.html",
"explanation": "Searchers are components in the query processing chain that can modify queries and results. Document Processors are components in the document processing chain that can modify incoming document operations.",
"difficulty": 2,
"topic": "Components"
},
{
"question": "What is the purpose of the `rank-score-drop-limit` in a rank profile?",
"options": [
"To discard documents with a first-phase rank score below the specified limit.",
"To limit the number of documents that are ranked in the second phase.",
"To specify a minimum rank score for a document to be included in the search results.",
"To prevent your rank score from falling off a cliff."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/schema-reference.html#rank-score-drop-limit",
"explanation": "The `rank-score-drop-limit` is a performance optimization that allows you to discard documents with a first-phase rank score below a certain threshold, preventing them from being evaluated in later phases.",
"difficulty": 4,
"topic": "Ranking"
},
{
"question": "What is the purpose of the `summary-features` in a rank profile?",
"options": [
"To include the values of specified rank features in the document summary.",
"To specify which features to use for generating the dynamic summary.",
"To control the formatting of the document summary.",
"To list the features of your favorite superhero."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/schema-reference.html#summary-features",
"explanation": "`summary-features` allows you to include the values of rank features in the document summary, which is useful for debugging and understanding why a document was ranked in a certain way.",
"difficulty": 3,
"topic": "Ranking"
},
{
"question": "What is the purpose of the `document-api` element in `services.xml`?",
"options": [
"To enable the Document API endpoint for feeding and retrieving documents.",
"To configure the security settings for the Document API.",
"To specify the threading model for the Document API.",
"To write an API for a documentary about Vespa."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/services-container.html#document-api",
"explanation": "The `<document-api>` element in `services.xml` enables the Document API endpoint, which is used for feeding, retrieving, updating, and deleting documents.",
"difficulty": 2,
"topic": "APIs"
},
{
"question": "How do you specify that a field should be stored as an attribute?",
"options": [
"By adding `attribute` to the `indexing` statement for the field.",
"By using the `@attribute` annotation in the document schema.",
"By creating a separate `attributes.xml` file.",
"By writing 'attribute' in big, bold letters next to the field definition."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/schema-reference.html#attribute",
"explanation": "To specify that a field should be stored as an attribute, you add the `attribute` keyword to the `indexing` statement for that field in the schema.",
"difficulty": 1,
"topic": "Data Modeling"
},
{
"question": "What is the purpose of the `vespa-get` tool?",
"options": [
"To retrieve one or more documents by their ID.",
"To get the status of a Vespa cluster.",
"To get the configuration of a Vespa application.",
"To get a life."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations-selfhosted/vespa-cmdline-tools.html#vespa-get",
"explanation": "`vespa-get` is a command-line tool that retrieves documents from a Vespa content cluster by their document IDs.",
"difficulty": 2,
"topic": "Operations"
},
{
"question": "What is the role of the 'cluster controller'?",
"options": [
"To manage the state of the distributor and content nodes.",
"To control the routing of queries to the content nodes.",
"To manage the deployment of application packages.",
"To be the designated driver for the cluster."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/content/content-nodes.html#cluster-controller",
"explanation": "The cluster controller manages the state of the distributor and content nodes. This cluster state is used to route document operations and queries.",
"difficulty": 3,
"topic": "Architecture"
},
{
"question": "What is the `distance-metric` attribute setting used for?",
"options": [
"To specify the distance metric for nearest neighbor search on a tensor field.",
"To calculate the distance between two geographical points.",
"To measure the similarity between two text documents.",
"To see how far you've come in life."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/schema-reference.html#distance-metric",
"explanation": "The `distance-metric` attribute setting is used to specify the distance metric (e.g., euclidean, angular) for nearest neighbor search on a tensor field.",
"difficulty": 3,
"topic": "Indexing & Search"
},
{
"question": "What is the `vespa-feed-client`?",
"options": [
"A Java library and command-line tool for high-performance feeding of documents to Vespa.",
"A graphical user interface for feeding documents to Vespa.",
"A REST API for feeding documents to Vespa.",
"A client that helps you find the best restaurants."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/vespa-feed-client.html",
"explanation": "`vespa-feed-client` is a high-performance Java library and command-line tool for feeding documents to Vespa asynchronously over HTTP.",
"difficulty": 3,
"topic": "Writes"
},
{
"question": "How can you specify that a query should be untranked?",
"options": [
"By setting `ranking.profile=unranked`.",
"By setting `ranking=false`.",
"By omitting the `ranking` parameter.",
"By giving it a participation trophy."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/query-api-reference.html#ranking.profile",
"explanation": "You can specify that a query should not be ranked by setting the `ranking.profile` parameter to `unranked`.",
"difficulty": 3,
"topic": "Querying"
},
{
"question": "What is the purpose of the 'OSGi' framework in Vespa?",
"options": [
"To provide a modular platform for developing applications with reusable components.",
"To manage the dependencies of your application.",
"To provide a secure environment for running your application.",
"A really cool-sounding acronym."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/components/bundles.html#osgi",
"explanation": "The Vespa Container uses OSGi to provide a modular platform for developing applications that can be composed of many reusable components (bundles) that can be deployed, upgraded, and removed at runtime.",
"difficulty": 4,
"topic": "Components"
},
{
"question": "What is the `vespa-get-cluster-state` tool used for?",
"options": [
"To get the state of a content cluster.",
"To get the status of the nodes in a content cluster.",
"To get the distribution of buckets in a content cluster.",
"To check the cluster's relationship status on Facebook."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/operations-selfhosted/vespa-cmdline-tools.html#vespa-get-cluster-state",
"explanation": "`vespa-get-cluster-state` is a command-line tool used to retrieve and display the state of a Vespa content cluster.",
"difficulty": 3,
"topic": "Operations"
},
{
"question": "What does the `global='true'` attribute on a document type in `services.xml` signify?",
"options": [
"That all documents of this type will be distributed to all nodes in the content cluster.",
"That documents of this type are not garbage collected.",
"That documents of this type can be accessed from any application.",
"That the documents have been around the world."
],
"answer": 0,
"link": "https://docs.vespa.ai/en/reference/services-content.html#document",
"explanation": "Setting `global='true'` for a document type ensures that all documents of this type are distributed to all nodes in the content cluster, which is a requirement for parent documents in parent-child relationships.",
"difficulty": 4,
"topic": "Data Modeling"
}
]
}
"""
# Load the sample quiz data
quiz_data = json.loads(quiz_data_json)
def get_difficulty_display(difficulty: int) -> str:
"""Convert difficulty level (1-4) to visual representation."""
difficulty_map = {
1: "⭐ Easy",
2: "⭐⭐ Medium",
3: "⭐⭐⭐ Hard",
4: "⭐⭐⭐⭐ Very Hard"
}
return difficulty_map.get(difficulty, "⭐ Easy")
class QuizApp(App):
"""Textual Application for the Quiz UI."""
CSS = "" # (We can define custom CSS here if needed for styling)
BINDINGS = [
Binding("q", "quit", "Quit", show=True), # Press 'q' to quit the quiz
# (Other global key bindings can be added here if desired)
]
COMMAND_PALETTE_BINDING = "ctrl+o"
def __init__(self, quiz):
super().__init__()
self.quiz = quiz
self.current_index = 0
self.score = 0
self.answered = False # Flag to indicate if current question was answered
# Will be set in on_mount to initial question data
self.question_widget = None
self.options_list = None
self.hint_widget = None
self.explanation_widget = None
self.progress_bar = None
def on_mount(self) -> None:
"""Called when the app is mounted (initialized). Setup initial state."""
# Set the title and subtitle for Header from metadata
self.title = self.quiz.get("title", "Quiz")
# Show description in subtitle if present
desc = self.quiz.get("description", "")
self.sub_title = desc if desc else ""
# Disable the clock in the header for simplicity
header = self.query_one(Header)
header.show_clock = False
# Initialize the first question
self._load_question(0)
def compose(self) -> ComposeResult:
"""Compose the UI layout by yielding widgets."""
# Header and Footer for overall layout
yield Header()
# Static widget for question text (will update per question)
self.question_widget = Static("", id="question")
# You can style question text: e.g., make it bold or underlined via markup
# We'll use underline style for question text for clarity
self.question_widget.update("")
yield self.question_widget
# ListView for options
self.options_list = ListView(id="options")
yield self.options_list
# Static widget for keyboard hints
self.hint_widget = Static("", id="hint")
yield self.hint_widget
# Static widget for explanation (initially empty)
self.explanation_widget = Static("", id="explanation")
yield self.explanation_widget
# Progress bar at bottom to show progress
total_questions = len(self.quiz.get("questions", []))
self.progress_bar = ProgressBar(total=total_questions, id="progress")
yield self.progress_bar
# Footer with key bindings (e.g., "q Quit")
yield Footer()
def _load_question(self, index: int):
"""Load the question at the given index into the UI."""
questions = self.quiz["questions"]
if index < 0 or index >= len(questions):
return
q = questions[index]
# Update question text (with question number and text)
question_num = index + 1
total = len(questions)
# Get topic and difficulty
topic = q.get("topic", "General")
difficulty = q.get("difficulty", 1)
difficulty_display = get_difficulty_display(difficulty)
# Create formatted question with metadata
question_text = f"Question {question_num}/{total}: {q['question']}\n"
question_text += f"[dim cyan]πŸ“š Topic: {topic}[/dim cyan] [dim yellow]{difficulty_display}[/dim yellow]"
# Underline the question text for emphasis
self.question_widget.update(f"[underline]{question_text}[/underline]")
# Populate the options list
self.options_list.clear() # Remove any previous options
self.current_option_labels = [] # keep references to label widgets for coloring
for i, opt in enumerate(q["options"]):
# Add subtle keyboard shortcut indicator to each option
option_text = f"[dim]{i+1}.[/dim] {opt}"
label = Static(option_text) # create a Static (or Label) for option text
item = ListItem(label)
self.options_list.append(item)
self.current_option_labels.append(label)
# Reset explanation and answered state
self.explanation_widget.update("") # clear explanation text
self.answered = False
# Show hint for answering
self.hint_widget.update("[dim italic]πŸ’‘ Press 1-4 to answer, or use ↑↓/j/k + Space/Enter[/dim italic]")
# Focus the options list so the user can navigate it
self.options_list.focus()
# Set initial focus to first option
if len(self.options_list) > 0:
self.options_list.index = 0
def _show_explanation(self, correct: bool, chosen_idx: int):
"""Display explanation and highlight correct/incorrect answers."""
q = self.quiz["questions"][self.current_index]
correct_idx = q["answer"]
# Highlight the correct answer in green, and wrong choice in red
for idx, label in enumerate(self.current_option_labels):
option_text = q["options"][idx]
shortcut_prefix = f"[dim]{idx+1}.[/dim] "
if idx == correct_idx:
# Mark correct answer
label.update(f"{shortcut_prefix}[b green]βœ” {option_text}[/b green]")
elif idx == chosen_idx and idx != correct_idx:
# Mark user's wrong answer
label.update(f"{shortcut_prefix}[b red]βœ– {option_text}[/b red]")
else:
# Keep other options with just the shortcut
label.update(f"{shortcut_prefix}{option_text}")
# Update score if answered correctly
if correct:
self.score += 1
# Show explanation text with perhaps dim styling
explanation_text = q.get("explanation", "")
read_more_link = q.get("link", "")
if read_more_link:
explanation_text += f"\n✨ Read more: {read_more_link}"
# Use italic style for explanation
self.explanation_widget.update(f"[dim italic]{explanation_text}[/dim italic]")
# Update hint to show how to continue
self.hint_widget.update("[dim italic]πŸ’‘ Press Enter or Space to continue[/dim italic]")
# Set answered flag and remove focus from list to prevent further selection
self.answered = True
self.options_list.blur() # remove focus from options
# Move progress bar one step
self.progress_bar.advance(1)
def on_list_view_selected(self, event: ListView.Selected) -> None:
"""Handle selection of an answer from the options ListView."""
if self.answered:
# If already answered (shouldn't happen due to our logic), ignore
return
selected_index = event.index
q = self.quiz["questions"][self.current_index]
correct_index = q["answer"]
is_correct = (selected_index == correct_index)
# Show feedback and explanation
self._show_explanation(correct=is_correct, chosen_idx=selected_index)
# Prompt (in footer or explanation) to continue
# (We could update footer or show a hint here, but for simplicity just rely on Enter binding)
def on_key(self, event) -> None:
"""Global key handler for custom shortcuts (numbers for options, j/k navigation, Enter/Space to answer/continue)."""
# Vim-style navigation: j (down) and k (up)
if not self.answered and event.key == "j":
# Move down in the list
if self.options_list.index < len(self.options_list) - 1:
self.options_list.index += 1
elif not self.answered and event.key == "k":
# Move up in the list
if self.options_list.index > 0:
self.options_list.index -= 1
# Space to select current option (before answered)
elif not self.answered and event.key == "space":
selected_idx = self.options_list.index
questions = self.quiz["questions"]
self._show_explanation(correct=(selected_idx == questions[self.current_index]["answer"]),
chosen_idx=selected_idx)
# Number key shortcuts for selecting an option directly
elif not self.answered and event.character and event.character.isdigit():
num = int(event.character)
questions = self.quiz["questions"]
if num > 0 and num <= len(questions[self.current_index]["options"]):
# Simulate selecting that option
selected_idx = num - 1
# Manually trigger the selection logic
self._show_explanation(correct=(selected_idx == questions[self.current_index]["answer"]),
chosen_idx=selected_idx)
# If an explanation is being shown, Enter or Space should go to next question
elif self.answered and event.key in ("enter", "space"):
next_index = self.current_index + 1
if next_index < len(self.quiz["questions"]):
self.current_index = next_index
self._load_question(next_index)
else:
# No more questions, quiz end – show final score
total = len(self.quiz["questions"])
result_text = f"πŸŽ‰ Quiz complete! You scored {self.score}/{total}."
result_text += "\nPress Q to quit."
self.question_widget.update(result_text)
# Clear options and explanation for a clean end screen
self.options_list.clear()
self.explanation_widget.update("")
# Optionally, show any provided links from metadata
links = self.quiz.get("links", [])
if links:
links_text = "πŸ“˜ Further reading:\n" + "\n".join(f"- {link}" for link in links)
self.explanation_widget.update(links_text)
# Set answered to False to avoid entering this block repeatedly
self.answered = False
# Run the app with the sample quiz data
if __name__ == "__main__":
app = QuizApp(quiz_data)
app.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment