[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"me":3,"catalog:en:ai-engineer\u002Faipy-async-concurrency-ml-serving":4,"config":193},null,{"field_key":5,"field_name":6,"seniority":7,"topic_key":8,"topic_name":9,"spec_key":7,"spec_name":7,"locale":10,"cell_total":11,"field_total":12,"seniorities":13,"topics":17,"specs":97,"samples":108},"ai-engineer","AI Engineer","","aipy-async-concurrency-ml-serving","Aipy Async Concurrency Ml Serving","en",75,2025,[14,15,16],"junior","mid","senior",[18,21,24,27,30,33,36,39,40,43,46,49,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94],{"key":19,"name":20,"count":11},"agents-tool-use","Agents Tool Use",{"key":22,"name":23,"count":11},"aimlops-deployment-strategies-ml","Aimlops Deployment Strategies Ml",{"key":25,"name":26,"count":11},"aimlops-experiment-tracking-reproducibility","Aimlops Experiment Tracking Reproducibility",{"key":28,"name":29,"count":11},"aimlops-feature-store-data-versioning","Aimlops Feature Store Data Versioning",{"key":31,"name":32,"count":11},"aimlops-ml-cicd-pipelines","Aimlops Ml Cicd Pipelines",{"key":34,"name":35,"count":11},"aimlops-model-monitoring-drift-detection","Aimlops Model Monitoring Drift Detection",{"key":37,"name":38,"count":11},"aimlops-model-versioning-registry","Aimlops Model Versioning Registry",{"key":8,"name":9,"count":11},{"key":41,"name":42,"count":11},"aipy-data-pipeline-dataloader","Aipy Data Pipeline Dataloader",{"key":44,"name":45,"count":11},"aipy-gpu-memory-management","Aipy Gpu Memory Management",{"key":47,"name":48,"count":11},"aipy-numpy-vectorization-broadcasting","Aipy Numpy Vectorization Broadcasting",{"key":50,"name":51,"count":11},"aipy-python-ml-packaging-environments","Aipy Python Ml Packaging Environments",{"key":53,"name":54,"count":11},"aipy-tensor-ops-autograd","Aipy Tensor Ops Autograd",{"key":56,"name":57,"count":11},"embeddings-vector-search","Embeddings Vector Search",{"key":59,"name":60,"count":11},"evaluation-testing","Evaluation Testing",{"key":62,"name":63,"count":11},"fine-tuning-adaptation","Fine Tuning Adaptation",{"key":65,"name":66,"count":11},"inference-serving","Inference Serving",{"key":68,"name":69,"count":11},"llm-fundamentals","Llm Fundamentals",{"key":71,"name":72,"count":11},"prompt-engineering","Prompt Engineering",{"key":74,"name":75,"count":11},"rag-chunking-indexing","Rag Chunking Indexing",{"key":77,"name":78,"count":11},"rag-embeddings-similarity","Rag Embeddings Similarity",{"key":80,"name":81,"count":11},"rag-evaluation","Rag Evaluation",{"key":83,"name":84,"count":11},"rag-generation-context","Rag Generation Context",{"key":86,"name":87,"count":11},"rag-reranking-fusion","Rag Reranking Fusion",{"key":89,"name":90,"count":11},"rag-retrieval","Rag Retrieval",{"key":92,"name":93,"count":11},"rag-retrieval-search","Rag Retrieval Search",{"key":95,"name":96,"count":11},"safety-guardrails","Safety Guardrails",[98,102,105],{"key":99,"name":100,"count":101},"llm-rag","LLM\u002FRAG",450,{"key":103,"name":104,"count":101},"mlops","MLOps",{"key":106,"name":107,"count":101},"python","Python",[109,127,140,154,167,180],{"id":110,"topic":9,"difficulty":111,"body":112,"options":113,"correct_key":121,"explanation":126},"019f9407-fb56-7eaa-a163-6d10758cb80c",1,"In standard CPython, what does the Global Interpreter Lock (GIL) guarantee about threads running inside a single process?",[114,117,120,123],{"key":115,"text":116},"a","Threads are forbidden from calling into any C extension, since the GIL blocks all native code paths.",{"key":118,"text":119},"b","Each thread gets its own dedicated CPU core, so bytecode execution is fully parallel across cores.",{"key":121,"text":122},"c","Only one thread executes Python bytecode at a time, even if the machine has multiple CPU cores.",{"key":124,"text":125},"d","The GIL only exists during process startup and is dropped once the first thread finishes importing modules.","The GIL is a mutex that lets only one thread execute Python bytecode at a time in a standard CPython process, regardless of how many CPU cores are available. (b) describes true multi-core parallelism, which the GIL specifically prevents for Python bytecode. (c) is false — C extensions can and often do release the GIL. (d) invents a startup-only lifetime that doesn't match how the GIL works.",{"id":128,"topic":9,"difficulty":111,"body":129,"options":130,"correct_key":115,"explanation":139},"019f9407-fb9f-7f10-a566-9047c2cfc731","A team runs a CPU-bound tokenization\u002Fpreprocessing function on 4 `threading.Thread` instances, hoping it will finish about 4x faster on a 4-core machine. What actually happens in standard CPython?",[131,133,135,137],{"key":115,"text":132},"It gives little to no speedup, because the GIL still lets only one thread run Python bytecode at a time.",{"key":118,"text":134},"It runs almost exactly 4x faster, since each thread claims one core for pure Python computation.",{"key":121,"text":136},"It runs slower than 1 thread by roughly 4x, since the GIL fully serializes all 4 threads end to end with no overlap.",{"key":124,"text":138},"The threads raise a RuntimeError at creation time, since CPython refuses more than one CPU-bound thread.","For CPU-bound, pure-Python work, the GIL means the 4 threads still take turns executing bytecode on effectively one core, so there is little to no real speedup — this is exactly why multiprocessing is preferred for CPU-bound Python work. (a) describes true parallelism the GIL prevents. (c) overstates the slowdown; there's some minor GIL-switching overhead, not a 4x penalty. (d) invents a restriction that doesn't exist — threads are created and run fine, just not in parallel for bytecode.",{"id":141,"topic":9,"difficulty":142,"body":143,"options":144,"correct_key":124,"explanation":153},"019f9407-fba7-7a6f-b9c8-90373dd466f2",2,"A model-serving endpoint makes a network call to a remote feature store and waits ~50ms for the response before running inference. Why does using `await` on that network call (instead of a blocking call) help serve more concurrent requests on the same single thread?",[145,147,149,151],{"key":115,"text":146},"It converts the network call into a CPU-bound operation, so the GIL no longer applies to it at all.",{"key":118,"text":148},"It causes the feature store to respond faster, since awaited calls are prioritized over blocking ones on the wire, similar to how QoS tagging reorders packets.",{"key":121,"text":150},"It spawns a new OS thread behind the scenes for every awaited call, so the wait happens in parallel automatically.",{"key":124,"text":152},"While waiting on I\u002FO, the coroutine yields control back to the event loop, letting other requests run.","`await` on an I\u002FO operation suspends that coroutine and returns control to the event loop, which can then run other pending coroutines while the network response is in flight — this is the core benefit of async for I\u002FO-bound waiting. (a) misdescribes network I\u002FO as CPU-bound. (b) invents network-level prioritization that doesn't exist. (d) describes a thread-per-call model, not how asyncio's single-threaded event loop works.",{"id":155,"topic":9,"difficulty":142,"body":156,"options":157,"correct_key":118,"explanation":166},"019f9407-fbc6-7a6a-a203-071c86689bee","Inside an `async def` request handler, a developer calls a synchronous, CPU-heavy inference function directly (no `await`, no offloading) that takes 200ms to run. What is the effect on other concurrent requests handled by the same event loop during that 200ms?",[158,160,162,164],{"key":115,"text":159},"Other coroutines keep running normally, since `async def` handlers are always non-blocking by definition.",{"key":118,"text":161},"The event loop is blocked for the full 200ms, so no other coroutine — including unrelated requests — can make progress.",{"key":121,"text":163},"The event loop pauses accepting new connections but keeps processing already-scheduled coroutines at full speed.",{"key":124,"text":165},"Only requests from other client IP addresses are delayed; requests from the same client continue unaffected.","A synchronous, CPU-bound call inside a coroutine runs on the same single thread as the event loop and never yields control, so it blocks the entire event loop for its whole duration — every other pending coroutine stalls too. (a) is false; declaring a function `async def` doesn't make blocking code inside it non-blocking. (b) and (c) invent partial-blocking behaviors that don't reflect how a single-threaded event loop works.",{"id":168,"topic":9,"difficulty":111,"body":169,"options":170,"correct_key":118,"explanation":179},"019f9407-fbc8-7554-aeaa-e1c31e6c3650","In the context of a Python model-serving API, what best distinguishes 'I\u002FO-bound' work from 'CPU-bound' work?",[171,173,175,177],{"key":115,"text":172},"I\u002FO-bound work always runs faster than CPU-bound work, regardless of what the code actually does.",{"key":118,"text":174},"I\u002FO-bound work spends most of its time waiting on external systems; CPU-bound work spends most of its time computing.",{"key":121,"text":176},"CPU-bound work is any code inside an `async def` function, while I\u002FO-bound work is any code inside a regular `def` function.",{"key":124,"text":178},"I\u002FO-bound work only applies to reading files from disk; any network call is classified as CPU-bound instead, because sockets are managed by kernel threads.","The distinction is about where time is actually spent: I\u002FO-bound work (e.g. waiting on a network response or a disk read) is mostly idle waiting, while CPU-bound work (e.g. tensor math, tokenization loops) is mostly active computation — this distinction drives whether async, threads, or processes help. (b) makes a false universal speed claim. (c) confuses the `async def`\u002F`def` syntax with the actual nature of the work. (d) wrongly excludes network calls from I\u002FO-bound work.",{"id":181,"topic":9,"difficulty":142,"body":182,"options":183,"correct_key":124,"explanation":192},"019f9407-fbcc-7d7c-8052-e1fbb6a5f42a","```python\nimport asyncio\n\nasync def handle_request(req):\n    result = run_cpu_heavy_inference(req)  # sync, ~150ms CPU work\n    return result\n\nasync def main():\n    await asyncio.gather(*(handle_request(r) for r in requests))\n```\nWith 10 requests in `requests`, roughly how long does `asyncio.gather` take, and why?",[184,186,188,190],{"key":115,"text":185},"About 150ms total, since `asyncio.gather` runs all 10 coroutines' CPU work truly in parallel on separate cores.",{"key":118,"text":187},"It hangs indefinitely, since `run_cpu_heavy_inference` is not itself declared with `async def`.",{"key":121,"text":189},"About 15ms total, since `asyncio.gather` splits the CPU work evenly across all requests automatically.",{"key":124,"text":191},"About 1500ms total, since each `handle_request` call blocks the event loop for its full 150ms with nothing overlapping.","Calling a synchronous, CPU-bound function directly inside a coroutine (no `await`, no offloading to a thread\u002Fprocess) blocks the single event loop thread for the full duration of each call; with 10 requests run back to back with no overlap, total time is roughly 10 x 150ms = 1500ms. (a) describes true parallel execution across cores, which `asyncio.gather` alone does not provide for blocking sync calls. (c) invents automatic work-splitting that doesn't exist. (d) is wrong — calling a plain sync function from a coroutine works fine, it's just blocking.",{"fields":194,"seniorities":372,"interview_shapes":373,"locales":378,"oauth":380,"question_count":383,"coach_enabled":384,"jd_match_enabled":384},[195,218,238,255,279,286,305,324,346,353,359,366],{"key":196,"name_tr":197,"name_en":197,"sort":111,"specializations":198},"backend","Backend",[199,202,205,206,209,212,215],{"key":200,"name":201,"field":196},"general","Genel",{"key":203,"name":204,"field":196},"go","Go",{"key":106,"name":107,"field":196},{"key":207,"name":208,"field":196},"java","Java",{"key":210,"name":211,"field":196},"csharp","C#\u002F.NET",{"key":213,"name":214,"field":196},"nodejs","Node.js",{"key":216,"name":217,"field":196},"php","PHP",{"key":219,"name_tr":220,"name_en":220,"sort":142,"specializations":221},"frontend","Frontend",[222,223,226,229,232,235],{"key":200,"name":201,"field":219},{"key":224,"name":225,"field":219},"javascript","JavaScript",{"key":227,"name":228,"field":219},"typescript","TypeScript",{"key":230,"name":231,"field":219},"react","React",{"key":233,"name":234,"field":219},"vue","Vue",{"key":236,"name":237,"field":219},"angular","Angular",{"key":239,"name_tr":240,"name_en":240,"sort":241,"specializations":242},"fullstack","Fullstack",3,[243,244,245,246,247,248,249,250,251,252,253,254],{"key":200,"name":201,"field":239},{"key":203,"name":204,"field":196},{"key":106,"name":107,"field":196},{"key":207,"name":208,"field":196},{"key":210,"name":211,"field":196},{"key":213,"name":214,"field":196},{"key":216,"name":217,"field":196},{"key":224,"name":225,"field":219},{"key":227,"name":228,"field":219},{"key":230,"name":231,"field":219},{"key":233,"name":234,"field":219},{"key":236,"name":237,"field":219},{"key":256,"name_tr":257,"name_en":257,"sort":258,"specializations":259},"devops-cloud","DevOps \u002F Cloud",4,[260,261,264,267,270,273,276],{"key":200,"name":201,"field":256},{"key":262,"name":263,"field":256},"aws","AWS",{"key":265,"name":266,"field":256},"gcp","GCP",{"key":268,"name":269,"field":256},"azure","Azure",{"key":271,"name":272,"field":256},"kubernetes","Kubernetes",{"key":274,"name":275,"field":256},"terraform","Terraform",{"key":277,"name":278,"field":256},"linux","Linux",{"key":5,"name_tr":6,"name_en":6,"sort":280,"specializations":281},5,[282,283,284,285],{"key":200,"name":201,"field":5},{"key":106,"name":107,"field":5},{"key":99,"name":100,"field":5},{"key":103,"name":104,"field":5},{"key":287,"name_tr":288,"name_en":289,"sort":290,"specializations":291},"database","Veritabanı","Database",6,[292,293,296,299,302],{"key":200,"name":201,"field":287},{"key":294,"name":295,"field":287},"postgresql","PostgreSQL",{"key":297,"name":298,"field":287},"mysql","MySQL",{"key":300,"name":301,"field":287},"mongodb","MongoDB",{"key":303,"name":304,"field":287},"redis","Redis",{"key":306,"name_tr":307,"name_en":308,"sort":309,"specializations":310},"mobile","Mobil","Mobile",7,[311,312,315,318,321],{"key":200,"name":201,"field":306},{"key":313,"name":314,"field":306},"ios-swift","iOS (Swift)",{"key":316,"name":317,"field":306},"android-kotlin","Android (Kotlin)",{"key":319,"name":320,"field":306},"flutter","Flutter",{"key":322,"name":323,"field":306},"react-native","React Native",{"key":325,"name_tr":326,"name_en":327,"sort":328,"specializations":329},"security","Güvenlik","Security",8,[330,331,334,337,340,343],{"key":200,"name":201,"field":325},{"key":332,"name":333,"field":325},"appsec","AppSec",{"key":335,"name":336,"field":325},"offensive-pentest","Offensive \u002F Pentest",{"key":338,"name":339,"field":325},"cloud-security","Cloud Security",{"key":341,"name":342,"field":325},"devsecops","DevSecOps",{"key":344,"name":345,"field":325},"blue-team-incident","Blue Team \u002F Incident",{"key":347,"name_tr":348,"name_en":349,"sort":350,"specializations":351},"qa-test-automation","QA \u002F Test Otomasyonu","QA \u002F Test Automation",9,[352],{"key":200,"name":201,"field":347},{"key":354,"name_tr":355,"name_en":355,"sort":356,"specializations":357},"data-engineer","Data Engineer",10,[358],{"key":200,"name":201,"field":354},{"key":360,"name_tr":361,"name_en":362,"sort":363,"specializations":364},"game-dev","Oyun Geliştirme","Game Development",11,[365],{"key":200,"name":201,"field":360},{"key":367,"name_tr":368,"name_en":368,"sort":369,"specializations":370},"ml-engineer","ML Engineer",12,[371],{"key":200,"name":201,"field":367},[14,15,16],{"junior":374,"mid":376,"senior":377},{"questions":375,"median_sec":3},20,{"questions":375,"median_sec":3},{"questions":375,"median_sec":3},[379,10],"tr",[381,382],"google","github",21750,true]