AI / LangChain4j interview questions
What is the difference between synchronous and asynchronous execution in LangChain4j?
LangChain4j supports both synchronous and asynchronous execution models for LLM calls. The choice affects how your application thread behaves while waiting for the (potentially slow) LLM response.
Synchronous — The calling thread blocks until the complete response is received. This is the default and simplest mode, appropriate for batch jobs, background tasks, and thread-per-request servers where thread blocking is acceptable.
// Sync: thread blocks until response arrives (may take 5-30 seconds) String answer = assistant.chat("What is quantum computing?");
Asynchronous (CompletableFuture) — Declare the return type as CompletableFuture<String> (or any other response type) in your AI Services interface. LangChain4j submits the call on a separate thread and returns immediately with a future:
interface AsyncAssistant { CompletableFuture<String> chat(String message); CompletableFuture<ProductReview> analyze(String review); // works with POJOs too } // Non-blocking: returns immediately, response arrives later CompletableFuture<String> future = assistant.chat("Explain blockchain"); future.thenAccept(answer -> System.out.println("Got answer: " + answer)); // ... continue doing other work ...
Streaming (TokenStream) — Token-by-token delivery. Neither sync nor truly async — it is event-driven and provides progressive output rather than waiting for the full response or getting it all at once later. Best for UI responsiveness.
For Spring WebFlux applications, the recommended pattern is returning Flux<String> by bridging LangChain4j's TokenStream to a reactive publisher via Sinks.Many or a FluxSink. Pure CompletableFuture works for non-streaming Spring MVC async (DeferredResult) or WebFlux scenarios.
More Related questions...