Android Retrofit Interview Questions

Networking, interceptors, and error handling.

50 questions in this topic · 8 sample questions below

Practice Retrofit in the quiz engine

Sample questions

  1. In OkHttp, what is the key difference between an application interceptor and a network interceptor?

    • A network interceptor is not invoked at all for a response served from the cache, whereas an application interceptor always runs once per Call — correct
    • Application interceptors always run on a background thread while network interceptors run on the main thread
    • Application interceptors can see redirects and retries but network interceptors cannot
    • Only network interceptors are allowed to modify the request body

    Why: Application interceptors run once per call regardless of caching or redirects; network interceptors sit closer to the wire and are skipped entirely on a full cache hit. The claim that a network interceptor sees cache hits is the classic misconception.

  2. Why is OkHttp's Authenticator preferred over a plain interceptor for OAuth token refresh?

    • The Authenticator runs before the request is sent so it can preemptively attach a fresh token
    • The Authenticator is invoked reactively only after a 401 response, letting you refresh and retry with the correct credentials, and OkHttp caps retries to avoid loops — correct
    • An interceptor cannot add an Authorization header at all
    • The Authenticator automatically deduplicates concurrent refresh calls with no extra code

    Why: Authenticator is a reactive challenge handler triggered on 401/407 that returns a new authenticated request, and OkHttp limits its retries. It does not run preemptively, and it does not deduplicate concurrent refreshes for you, so single-flight synchronization is still your responsibility.

  3. Several requests get 401 at once and each triggers a token refresh. What is the correct single-flight strategy?

    • Let every request refresh independently since OkHttp will merge them
    • Disable the connection pool so requests serialize automatically
    • Guard refresh with a mutex or synchronized block and, once a new token exists, have waiting requests reuse it instead of refreshing again — correct
    • Increase the read timeout so the 401s never overlap

    Why: You synchronize the refresh and re-check whether the token already changed before refreshing, so only one network refresh happens and the rest reuse the result. OkHttp does not merge concurrent refreshes, and timeouts or pool tweaks do not address the race.

  4. Does Retrofit automatically retry a request that failed with an IOException?

    • Yes, Retrofit retries up to three times by default
    • Yes, but only for GET requests
    • No, but OkHttp retries every failed request indefinitely
    • No, Retrofit performs no automatic retries; retry and backoff is something you add via an interceptor or caller logic — correct

    Why: Retrofit does not implement retries; a failed call surfaces the exception to you. OkHttp only transparently recovers from certain connection-level failures when retryOnConnectionFailure is on, which is not the same as retrying application errors.

  5. With a Retrofit suspend function returning a plain type like User, what happens on a non-2xx HTTP response?

    • It throws an HttpException carrying the response code and error body — correct
    • It returns null
    • It throws an IOException
    • It silently returns an empty User instance

    Why: A suspend function returning a bare body type throws HttpException on non-2xx, while network failures throw IOException. Returning null or an empty object would require you to wrap the return in Response or Result yourself.

  6. When a Retrofit call returns HTTP 422 with a JSON error body, how do you read that body?

    • Call response.body() which now holds the error payload
    • Call response.errorBody() and parse it, optionally via a Converter obtained from retrofit.responseBodyConverter — correct
    • The error body is unavailable; only the status code is exposed
    • Read exception.getMessage() which contains the full JSON

    Why: On an unsuccessful response the payload is in errorBody(), not body(), and you can parse it with a matching converter. body() is null for non-2xx, and the exception message does not contain the parsed error object.

  7. Why is an HTTP POST response generally not served from the OkHttp cache?

    • OkHttp lacks any code path to cache POST
    • POST responses are always larger than the cache limit
    • POST is not idempotent and HTTP caching semantics only define storable, reusable responses for safe methods like GET — correct
    • POST always includes a no-store header added by Retrofit

    Why: HTTP caching is defined around safe, idempotent methods; POST responses are not cached because they typically represent state changes. It is a protocol semantics decision, not a size limit or a header Retrofit injects.

  8. How does a conditional GET with an ETag reduce bandwidth?

    • The server compresses the body more aggressively when an ETag is present
    • The client sends If-Modified-Since which the server ignores for ETags
    • The ETag lets the client skip TLS renegotiation
    • The client sends If-None-Match with the stored ETag and the server may reply 304 Not Modified with no body, letting the client reuse the cached copy — correct

    Why: The stored ETag is echoed in If-None-Match; a 304 tells the client its cached body is still valid, avoiding retransmission. If-Modified-Since is the date-based validator and is not the ETag mechanism.

Practice all 50 Retrofit questions

These 8 are a sample. The full Retrofit bank is scored, tracks your progress, and explains every answer.

Open the quiz

More Android interview topics