Snowflake SnowPro Advanced: Architect (ARA-C01) · 25% practice allocation

Snowflake ARA-C01: Data Engineering Practice Questions

5 free sample questions from the Data Engineering domain, with answers and explanations. The full ARA-C01 bank has 214 questions across 4 domains. Questions are scenario-based and written from the official Snowflake exam guide.

1.

An architect is designing a Snowflake Native App that will be published on the Snowflake Marketplace. The app must allow the consumer to install it in their own Snowflake account and query provider-owned data without the provider ever exposing the underlying tables directly. Which two features of the Native App Framework enable this pattern? (Select TWO.)

  • A. External tables pointing to a provider-owned S3 bucket, allowing consumers to query raw files without table grants
  • B. Data Sharing via a listing, so the app installs a reference to the provider's share inside the consumer account
  • C. Shared databases attached to the application package, so the consumer account queries provider data through the app's versioned objects✓ Correct
  • D. Secure Views defined inside the application package, which restrict column-level access to the underlying provider data
  • E. Application roles granted to consumers, which scope permissions to only the objects exposed by the app✓ Correct
Explanation

In the Native App Framework, the APPLICATION PACKAGE acts as a container that bundles the application logic with references to provider data (via shares included in the package). Consumers install the app from the package, querying provider data only through the app's versioned objects — the underlying tables are never directly shared. APPLICATION ROLES are defined inside the app and granted to consumer users, scoping exactly which app objects they can access. Option D (Secure Views) is a general Snowflake feature and not a Native App-specific mechanism; while views can be used inside an app, they alone do not define the Native App data-isolation model. Option B confuses a Marketplace listing (a distribution mechanism) with the architectural pattern; the listing is how the app is published, not how data isolation is enforced. Option A (External tables on provider S3) would expose the provider's storage outside Snowflake's control and is not a Native App pattern.

2.

A team is implementing a Snowpark Python UDTF (User-Defined Table Function) to parse nested JSON log records and emit multiple output rows per input row. The handler class currently implements only the process() method. The team notices that some aggregated state they initialize in __init__ is not reset between partitions, causing incorrect results. Which two changes will correctly fix this issue? (Select TWO.)

  • A. Initialize all mutable partition state inside the process() method using a conditional check on the first row, rather than in __init__.✓ Correct
  • B. Move all partition-level state initialization into the __init__ method and ensure the UDTF is declared with PARTITION BY to guarantee one class instance per partition.
  • C. Replace the UDTF with a UDF that returns a VARIANT containing an array of result objects, then flatten the array with LATERAL FLATTEN.
  • D. Increase the warehouse size so that each partition is processed by a separate virtual warehouse node, isolating state automatically.
  • E. Declare the handler class as @staticmethod so that no instance state is maintained between rows.
  • F. Implement the end_partition() method to emit any remaining buffered rows and reset mutable state, ensuring clean completion of each partition.✓ Correct
Explanation

In a Snowpark UDTF, a single handler class instance may be reused across partitions in some execution contexts. The correct patterns are: (1) Initialize mutable state inside process() with a guard (e.g., a flag set on the first call), ensuring it resets per logical partition boundary without relying on __init__ being called per partition; and (2) implement end_partition() to finalize and emit any buffered rows, which is called once at the end of each partition — this is the correct place to flush buffers and perform cleanup. Option B is partially correct in concept but incorrect in detail — __init__ is not guaranteed to be called per partition in all configurations; the PARTITION BY clause controls data routing, not class instantiation lifecycle. Option C is a valid workaround but changes the interface entirely and loses the multi-row output benefits of UDTFs. Option E (@staticmethod) is incorrect syntax for a handler class and would break the UDTF entirely. Option D (warehouse size) has no effect on Python handler instance lifecycle.

3.

A data scientist wants to train a scikit-learn RandomForestClassifier on data stored in Snowflake using the Snowpark ML Modeling API without moving data to a local machine. Which code pattern correctly achieves this?

  • A. Register a Python UDF that calls sklearn.fit() row-by-row inside Snowflake, then invoke the UDF via a SELECT statement.
  • B. Export the Snowpark DataFrame to an internal stage as a CSV, download it, train locally, then upload the model artifact back to the stage.
  • C. Use snowflake.ml.modeling.ensemble.RandomForestClassifier, fit it on a Snowpark DataFrame, and the API will push the training computation into Snowflake.✓ Correct
  • D. Call session.sql('SELECT * FROM training_data').collect() to retrieve a pandas DataFrame, then call sklearn.ensemble.RandomForestClassifier().fit() locally.
Explanation

The Snowpark ML Modeling API (snowflake.ml.modeling) provides sklearn-compatible estimator wrappers (e.g., RandomForestClassifier) that accept Snowpark DataFrames and push the training workload into Snowflake — data never leaves the platform. This is the purpose of the Snowpark ML Modeling API. Option D pulls all data to the client and trains locally, defeating the purpose of in-Snowflake ML and creating data transfer overhead. Option A is architecturally incorrect — sklearn.fit() requires an entire dataset, not individual rows, so it cannot be used in a row-level UDF; this pattern would produce nonsensical results. Option B manually exports and re-imports data, adding latency, cost, and data governance risk.

4.

A machine learning engineer is using the Snowpark ML Modeling API to build a preprocessing pipeline for a fraud-detection model. The pipeline includes a StandardScaler and an OrdinalEncoder from snowflake.ml.modeling.preprocessing, followed by a LogisticRegression estimator from snowflake.ml.modeling.linear_model. After calling pipeline.fit(train_df), the engineer calls pipeline.transform(test_df) but notices the resulting Snowpark DataFrame contains no materialized rows in the warehouse query history — only metadata operations appear. A colleague suggests the results are being silently dropped. What is the MOST likely and correct explanation for this behavior?

  • A. The StandardScaler and OrdinalEncoder preprocessing steps execute inside the Python UDF sandbox and do not emit query history entries by design; only the final estimator step appears in query history when predict() is called.
  • B. The Snowpark ML pipeline's transform() method automatically writes results to a transient internal stage, and the engineer must call pipeline.get_output_stage_location() to retrieve them.
  • C. The transform() call on a Snowpark ML pipeline returns a lazy Snowpark DataFrame; no computation is pushed to the Snowflake engine until a terminal action such as show(), collect(), or write.save_as_table() is explicitly called.✓ Correct
  • D. Because LogisticRegression is an estimator rather than a transformer, calling transform() on a pipeline that ends with an estimator raises a silent no-op; the engineer should call predict() on the fitted pipeline instead to obtain any output.
Explanation

Correct — Option C: Snowpark ML Modeling API objects (preprocessors, pipelines, estimators) are built on top of the Snowpark DataFrame API, which uses lazy evaluation. Calling fit() does trigger computation (to learn parameters), but transform() returns a new Snowpark DataFrame representing the transformation plan — it does not execute until a terminal action (collect(), show(), to_pandas(), write.save_as_table(), etc.) is invoked. This is consistent with the broader Snowpark DataFrame contract and is a common source of confusion for engineers migrating from eager-execution frameworks like pandas.

Wrong — Option B: There is no get_output_stage_location() method on Snowpark ML pipelines, and results are not automatically written to an internal stage. This reflects a misconception about how Snowpark ML handles output — it does not have a file-based intermediate output model.

Wrong — Option D: While it is true that calling transform() on a pipeline whose last step is a pure estimator (not a transformer) would raise an error in some ML frameworks (e.g., scikit-learn), the Snowpark ML Pipeline class mirrors scikit-learn conventions: if the last step is an estimator, transform() does raise an exception — but the question states the behavior is a silent no-op with no rows, not an error. The real cause is lazy evaluation, not the estimator-vs-transformer distinction. Additionally, predict() is the correct terminal call for inference, but that is a separate concern from why no computation appears.

Wrong — Option A: Snowpark ML preprocessing transformers do not universally execute inside a Python UDF sandbox; many operations (e.g., StandardScaler) are translated into SQL expressions pushed down to the Snowflake query engine and would appear in query history once a terminal action is triggered. The claim that they never appear in query history is incorrect and conflates the lazy-evaluation issue with the execution model.

5.

An architect is configuring an external function that calls an AWS Lambda function to perform real-time credit scoring. During load testing, the team observes that Snowflake sends very large batches to the Lambda, causing timeouts. Which TWO configuration options can the architect use to control batch sizing in the external function definition? (Select TWO.)

  • A. Set COMPRESSION = NONE in the API Integration to force Snowflake to send one row per HTTP request.
  • B. Use the REQUEST_TRANSLATOR parameter to write a JavaScript UDF that splits large arrays into smaller sub-arrays before sending.
  • C. Set MAX_BATCH_ROWS and configure the Lambda's reserved concurrency to match the expected number of concurrent Snowflake batch requests.✓ Correct
  • D. Set MAX_BATCH_ROWS in the CREATE EXTERNAL FUNCTION statement to limit the number of rows sent per HTTP request to the Lambda.✓ Correct
  • E. Reduce the warehouse size to X-Small, which limits the number of rows Snowflake can process per batch due to reduced memory.
Explanation

MAX_BATCH_ROWS is a parameter available in CREATE EXTERNAL FUNCTION that explicitly caps the number of rows Snowflake will include in a single HTTP batch request to the remote endpoint, directly addressing Lambda timeouts from oversized payloads. Pairing this with tuned Lambda reserved concurrency ensures the downstream service can handle the resulting parallel batch volume. Option A is incorrect — COMPRESSION in the API Integration controls payload compression format, not batch row count. Option B is incorrect — REQUEST_TRANSLATOR is used to reshape the request payload structure, not to split batches; Snowflake controls batching before the translator runs. Option E is incorrect — warehouse size influences query parallelism broadly but does not directly control external function batch sizes; it is not a reliable or recommended tuning lever for this problem.

Test yourself across every ARA-C01 domain

The free ARA-C01 practice test mixes about 20 questions weighted like the exam. The full 214-question bank adds instant grading, flashcards and a timed mock exam.

Study this domain

Data Engineering study guide (ARA-C01) →

Other ARA-C01 domains

← All Snowflake SnowPro Advanced: Architect study resources