[{"data":1,"prerenderedAt":22444},["ShallowReactive",2],{"navigation_docs":3,"-csharp-system-programming-windows-concurrent-collections":2949,"-csharp-system-programming-windows-concurrent-collections-surround":22439},[4,1640,1765,2219,2352,2559,2641,2691,2748,2782,2908,2945],{"title":5,"icon":6,"path":7,"stem":8,"children":9},"C#","i-devicon-csharp","/csharp","01.csharp",[10,13,60,90,120,202,219,253,379,404,457,650,1346,1636],{"title":11,"path":7,"stem":12},"C# Roadmap","01.csharp/index",{"title":14,"icon":15,"path":16,"stem":17,"children":18,"page":59},"Fundamentals","i-lucide-book-open","/csharp/fundamentals","01.csharp/01.fundamentals",[19,23,27,31,35,39,43,47,51,55],{"title":20,"path":21,"stem":22},"Вступ до екосистеми .NET","/csharp/fundamentals/introduction-to-ecosystem","01.csharp/01.fundamentals/01.introduction-to-ecosystem",{"title":24,"path":25,"stem":26},"Структура програми на C#","/csharp/fundamentals/program-structure","01.csharp/01.fundamentals/02.program-structure",{"title":28,"path":29,"stem":30},"Змінні та Типи Даних","/csharp/fundamentals/variables-data-types","01.csharp/01.fundamentals/03.variables-data-types",{"title":32,"path":33,"stem":34},"Масиви","/csharp/fundamentals/arrays","01.csharp/01.fundamentals/04.arrays",{"title":36,"path":37,"stem":38},"Strings & Text Handling","/csharp/fundamentals/strings-text-handling","01.csharp/01.fundamentals/05.strings-text-handling",{"title":40,"path":41,"stem":42},"Дати і Час","/csharp/fundamentals/dates-time-handling","01.csharp/01.fundamentals/06.dates-time-handling",{"title":44,"path":45,"stem":46},"Потік Керування","/csharp/fundamentals/control-flow","01.csharp/01.fundamentals/07.control-flow",{"title":48,"path":49,"stem":50},"Методи","/csharp/fundamentals/methods","01.csharp/01.fundamentals/08.methods",{"title":52,"path":53,"stem":54},"Основи Відлагодження","/csharp/fundamentals/debugging-basics","01.csharp/01.fundamentals/09.debugging-basics",{"title":56,"path":57,"stem":58},"Інтерактивна Консоль (Classic)","/csharp/fundamentals/interactive-console","01.csharp/01.fundamentals/10.interactive-console",false,{"title":61,"icon":62,"path":63,"stem":64,"children":65,"page":59},"OOP","i-lucide-box","/csharp/oop","01.csharp/02.oop",[66,70,74,78,82,86],{"title":67,"path":68,"stem":69},"Package Management (Управління Пакетами)","/csharp/oop/package-management","01.csharp/02.oop/01.package-management",{"title":71,"path":72,"stem":73},"Класи та Об'єкти","/csharp/oop/classes-objects","01.csharp/02.oop/02.classes-objects",{"title":75,"path":76,"stem":77},"Властивості та Поля","/csharp/oop/properties-fields","01.csharp/02.oop/03.properties-fields",{"title":79,"path":80,"stem":81},"Стовпи ООП","/csharp/oop/oop-pillars","01.csharp/02.oop/04.oop-pillars",{"title":83,"path":84,"stem":85},"Advanced Types","/csharp/oop/advanced-types","01.csharp/02.oop/05.advanced-types",{"title":87,"path":88,"stem":89},"Namespaces (Простори Імен)","/csharp/oop/namespaces","01.csharp/02.oop/06.namespaces",{"title":91,"icon":92,"path":93,"stem":94,"children":95,"page":59},"Advanced Core","i-lucide-zap","/csharp/advanced-core","01.csharp/03.advanced-core",[96,100,104,108,112,116],{"title":97,"path":98,"stem":99},"Generics (Узагальнення)","/csharp/advanced-core/generics","01.csharp/03.advanced-core/01.generics",{"title":101,"path":102,"stem":103},"Делегати, Події та Лямбда-вирази","/csharp/advanced-core/delegates-events-lambdas","01.csharp/03.advanced-core/02.delegates-events-lambdas",{"title":105,"path":106,"stem":107},"Interfaces Deep Dive (Інтерфейси: Поглиблений Розгляд)","/csharp/advanced-core/interfaces-deep-dive","01.csharp/03.advanced-core/03.interfaces-deep-dive",{"title":109,"path":110,"stem":111},"Обробка Винятків","/csharp/advanced-core/exception-handling","01.csharp/03.advanced-core/04.exception-handling",{"title":113,"path":114,"stem":115},"Pattern Matching","/csharp/advanced-core/pattern-matching","01.csharp/03.advanced-core/05.pattern-matching",{"title":117,"path":118,"stem":119},"Додаткові Можливості C#","/csharp/advanced-core/additional-features","01.csharp/03.advanced-core/06.additional-features",{"title":121,"icon":122,"path":123,"stem":124,"children":125,"page":59},"Architecture Best Practices","i-lucide-building-2","/csharp/architecture-best-practices","01.csharp/04.architecture-best-practices",[126,130,149,153,157,161,165,169],{"title":127,"path":128,"stem":129},"Software Design Principles (Частина 1)","/csharp/architecture-best-practices/software-design-principles","01.csharp/04.architecture-best-practices/01.software-design-principles",{"title":131,"icon":132,"path":133,"stem":134,"children":135,"page":59},"Design Patterns","i-lucide-folder","/csharp/architecture-best-practices/design-patterns","01.csharp/04.architecture-best-practices/02.design-patterns",[136],{"title":137,"icon":132,"path":138,"stem":139,"children":140,"page":59},"Creational","/csharp/architecture-best-practices/design-patterns/creational","01.csharp/04.architecture-best-practices/02.design-patterns/creational",[141,145],{"title":142,"path":143,"stem":144},"Singleton (Одинак)","/csharp/architecture-best-practices/design-patterns/creational/singleton","01.csharp/04.architecture-best-practices/02.design-patterns/creational/01.singleton",{"title":146,"path":147,"stem":148},"Builder (Будівельник)","/csharp/architecture-best-practices/design-patterns/creational/builder","01.csharp/04.architecture-best-practices/02.design-patterns/creational/02.builder",{"title":150,"path":151,"stem":152},"Building Professional CLIs","/csharp/architecture-best-practices/building-professional-clis","01.csharp/04.architecture-best-practices/03.building-professional-clis",{"title":154,"path":155,"stem":156},"Validation & Flow Control","/csharp/architecture-best-practices/validation-flow-control","01.csharp/04.architecture-best-practices/04.validation-flow-control",{"title":158,"path":159,"stem":160},"The Modern .NET Host (Microsoft.Extensions)","/csharp/architecture-best-practices/modern-dotnet-host","01.csharp/04.architecture-best-practices/05.modern-dotnet-host",{"title":162,"path":163,"stem":164},"Data Mapper: Repository та DAO патерни (Частина 1)","/csharp/architecture-best-practices/data-mapper-part1","01.csharp/04.architecture-best-practices/06.data-mapper-part1",{"title":166,"path":167,"stem":168},"Data Mapper: Repository та DAO патерни (Частина 2)","/csharp/architecture-best-practices/data-mapper-part2","01.csharp/04.architecture-best-practices/07.data-mapper-part2",{"title":170,"icon":132,"path":171,"stem":172,"children":173,"page":59},"Di Ioc","/csharp/architecture-best-practices/di-ioc","01.csharp/04.architecture-best-practices/08.di-ioc",[174,178,182,186,190,194,198],{"title":175,"path":176,"stem":177},"Проблема залежностей та Інверсія Контролю","/csharp/architecture-best-practices/di-ioc/the-dependency-problem","01.csharp/04.architecture-best-practices/08.di-ioc/01.the-dependency-problem",{"title":179,"path":180,"stem":181},"Будуємо власний Service Container","/csharp/architecture-best-practices/di-ioc/build-your-own-container","01.csharp/04.architecture-best-practices/08.di-ioc/02.build-your-own-container",{"title":183,"path":184,"stem":185},"Service Locator: Паттерн та Анти-паттерн","/csharp/architecture-best-practices/di-ioc/service-locator-pattern","01.csharp/04.architecture-best-practices/08.di-ioc/03.service-locator-pattern",{"title":187,"path":188,"stem":189},"Паттерни Dependency Injection","/csharp/architecture-best-practices/di-ioc/dependency-injection-patterns","01.csharp/04.architecture-best-practices/08.di-ioc/04.dependency-injection-patterns",{"title":191,"path":192,"stem":193},"Microsoft DI: IServiceCollection та IServiceProvider","/csharp/architecture-best-practices/di-ioc/microsoft-di-deep-dive","01.csharp/04.architecture-best-practices/08.di-ioc/05.microsoft-di-deep-dive",{"title":195,"path":196,"stem":197},"Service Lifetimes та Scopes","/csharp/architecture-best-practices/di-ioc/service-lifetimes-and-scopes","01.csharp/04.architecture-best-practices/08.di-ioc/06.service-lifetimes-and-scopes",{"title":199,"path":200,"stem":201},"DI Анти-паттерни та Найкращі Практики","/csharp/architecture-best-practices/di-ioc/di-anti-patterns-and-best-practices","01.csharp/04.architecture-best-practices/08.di-ioc/07.di-anti-patterns-and-best-practices",{"title":203,"icon":132,"path":204,"stem":205,"children":206,"page":59},"Standard Library","/csharp/standard-library","01.csharp/05.standard-library",[207,211,215],{"title":208,"path":209,"stem":210},"Collections (Колекції)","/csharp/standard-library/collections","01.csharp/05.standard-library/01.collections",{"title":212,"path":213,"stem":214},"High Performance Types (Високопродуктивні Типи)","/csharp/standard-library/high-performance-types","01.csharp/05.standard-library/02.high-performance-types",{"title":216,"path":217,"stem":218},"LINQ (Language Integrated Query)","/csharp/standard-library/linq","01.csharp/05.standard-library/03.linq",{"title":220,"icon":221,"path":222,"stem":223,"children":224,"page":59},"System Internals Concurrency","i-lucide-server","/csharp/system-internals-concurrency","01.csharp/06.system-internals-concurrency",[225,229,233,237,241,245,249],{"title":226,"path":227,"stem":228},"Memory Management","/csharp/system-internals-concurrency/memory-management","01.csharp/06.system-internals-concurrency/01.memory-management",{"title":230,"path":231,"stem":232},"Reflection API: System.Type та Метадані","/csharp/system-internals-concurrency/reflection-fundamentals","01.csharp/06.system-internals-concurrency/02.reflection-fundamentals",{"title":234,"path":235,"stem":236},"Attributes та Dynamic Language Runtime","/csharp/system-internals-concurrency/attributes-dynamic","01.csharp/06.system-internals-concurrency/03.attributes-dynamic",{"title":238,"path":239,"stem":240},"Expression Trees: Швидка Альтернатива Рефлексії","/csharp/system-internals-concurrency/expression-trees-compiled","01.csharp/06.system-internals-concurrency/04.expression-trees-compiled",{"title":242,"path":243,"stem":244},"Source Generators: Compile-Time Code Generation","/csharp/system-internals-concurrency/source-generators","01.csharp/06.system-internals-concurrency/05.source-generators",{"title":246,"path":247,"stem":248},"Multithreading Fundamentals","/csharp/system-internals-concurrency/multithreading-fundamentals","01.csharp/06.system-internals-concurrency/06.multithreading-fundamentals",{"title":250,"path":251,"stem":252},"Synchronization Primitives","/csharp/system-internals-concurrency/synchronization-primitives","01.csharp/06.system-internals-concurrency/07.synchronization-primitives",{"title":254,"icon":255,"path":256,"stem":257,"children":258,"page":59},"System Programming Windows","i-lucide-cpu","/csharp/system-programming-windows","01.csharp/07.system-programming-windows",[259,263,267,271,275,279,283,287,291,295,299,303,307,311,315,319,323,327,331,335,339,343,347,351,355,359,363,367,371,375],{"title":260,"path":261,"stem":262},"Як Працює Операційна Система","/csharp/system-programming-windows/how-os-works","01.csharp/07.system-programming-windows/01.how-os-works",{"title":264,"path":265,"stem":266},"Процеси в .NET — API та Запуск","/csharp/system-programming-windows/processes-in-dotnet","01.csharp/07.system-programming-windows/02.processes-in-dotnet",{"title":268,"path":269,"stem":270},"Процеси в .NET — IPC та Міжпроцесна Комунікація","/csharp/system-programming-windows/02a.processes-ipc","01.csharp/07.system-programming-windows/02a.processes-ipc",{"title":272,"path":273,"stem":274},"Application Domains та Збірки — AppDomain і AssemblyLoadContext","/csharp/system-programming-windows/appdomains-assemblies","01.csharp/07.system-programming-windows/03.appdomains-assemblies",{"title":276,"path":277,"stem":278},"Application Domains та Збірки — Plug-in Система з Hot-Reload","/csharp/system-programming-windows/03a.appdomains-plugin-system","01.csharp/07.system-programming-windows/03a.appdomains-plugin-system",{"title":280,"path":281,"stem":282},"Потоки — Основи та API Thread","/csharp/system-programming-windows/thread-fundamentals","01.csharp/07.system-programming-windows/04.thread-fundamentals",{"title":284,"path":285,"stem":286},"Потоки — Lifecycle, Пріоритети та Безпечне Завершення","/csharp/system-programming-windows/04a.thread-lifecycle-priorities","01.csharp/07.system-programming-windows/04a.thread-lifecycle-priorities",{"title":288,"path":289,"stem":290},"Проблеми Спільного Стану — Race Condition та Data Race","/csharp/system-programming-windows/shared-state-problems","01.csharp/07.system-programming-windows/05.shared-state-problems",{"title":292,"path":293,"stem":294},"Проблеми Спільного Стану — Memory Model та volatile","/csharp/system-programming-windows/05a.shared-state-memory-model","01.csharp/07.system-programming-windows/05a.shared-state-memory-model",{"title":296,"path":297,"stem":298},"Синхронізація — Monitor, lock та еволюція примітивів","/csharp/system-programming-windows/synchronization-fundamentals","01.csharp/07.system-programming-windows/06.synchronization-fundamentals",{"title":300,"path":301,"stem":302},"Синхронізація — Наскрізний Приклад та Deadlock Detection","/csharp/system-programming-windows/06a.synchronization-walkthrough","01.csharp/07.system-programming-windows/06a.synchronization-walkthrough",{"title":304,"path":305,"stem":306},"Синхронізація — Mutex, Semaphore та Event-Based Primitives","/csharp/system-programming-windows/synchronization-advanced","01.csharp/07.system-programming-windows/07.synchronization-advanced",{"title":308,"path":309,"stem":310},"Синхронізація — Interlocked, Volatile та Lock-Free Структури","/csharp/system-programming-windows/07a.synchronization-advanced-walkthrough","01.csharp/07.system-programming-windows/07a.synchronization-advanced-walkthrough",{"title":312,"path":313,"stem":314},"Interlocked, CAS та Lock-Free Структури","/csharp/system-programming-windows/interlocked-cas-lockfree","01.csharp/07.system-programming-windows/08.interlocked-cas-lockfree",{"title":316,"path":317,"stem":318},"Volatile, Memory Model та Spinning","/csharp/system-programming-windows/08a.volatile-memory-model","01.csharp/07.system-programming-windows/08a.volatile-memory-model",{"title":320,"path":321,"stem":322},"ThreadPool — Пул Потоків для Ефективного Виконання","/csharp/system-programming-windows/thread-pool","01.csharp/07.system-programming-windows/09.thread-pool",{"title":324,"path":325,"stem":326},"ThreadPool — Просунуті Сценарії та Внутрішня Будова","/csharp/system-programming-windows/09a.thread-pool-advanced","01.csharp/07.system-programming-windows/09a.thread-pool-advanced",{"title":328,"path":329,"stem":330},"Concurrent та Immutable Collections","/csharp/system-programming-windows/concurrent-collections","01.csharp/07.system-programming-windows/10.concurrent-collections",{"title":332,"path":333,"stem":334},"TPL, Task та Композиція — Від Thread до Task","/csharp/system-programming-windows/tpl-parallel-plinq","01.csharp/07.system-programming-windows/11.tpl-parallel-plinq",{"title":336,"path":337,"stem":338},"Parallel Class та PLINQ — Data Parallelism","/csharp/system-programming-windows/11a.tpl-parallel-plinq-advanced","01.csharp/07.system-programming-windows/11a.tpl-parallel-plinq-advanced",{"title":340,"path":341,"stem":342},"Async/Await — Фундамент Асинхронного Програмування","/csharp/system-programming-windows/async-fundamentals","01.csharp/07.system-programming-windows/12.async-fundamentals",{"title":344,"path":345,"stem":346},"SynchronizationContext та ConfigureAwait — Контекст Виконання","/csharp/system-programming-windows/async-context-configureawait","01.csharp/07.system-programming-windows/13.async-context-configureawait",{"title":348,"path":349,"stem":350},"Async — Просунуті Паттерни","/csharp/system-programming-windows/async-advanced","01.csharp/07.system-programming-windows/14.async-advanced",{"title":352,"path":353,"stem":354},"System.Threading.Channels — Async Producer-Consumer","/csharp/system-programming-windows/channels","01.csharp/07.system-programming-windows/15.channels",{"title":356,"path":357,"stem":358},"Асинхронна Синхронізація","/csharp/system-programming-windows/async-synchronization","01.csharp/07.system-programming-windows/16.async-synchronization",{"title":360,"path":361,"stem":362},"Unsafe Code та Вказівники","/csharp/system-programming-windows/unsafe-code","01.csharp/07.system-programming-windows/17.unsafe-code",{"title":364,"path":365,"stem":366},"P/Invoke та Windows API — Міст між .NET та Native Code","/csharp/system-programming-windows/pinvoke-winapi","01.csharp/07.system-programming-windows/18.pinvoke-winapi",{"title":368,"path":369,"stem":370},"Реєстр Windows — Центральна База Конфігурації Системи","/csharp/system-programming-windows/windows-registry","01.csharp/07.system-programming-windows/19.windows-registry",{"title":372,"path":373,"stem":374},"Windows Hooks, Hotkeys та Services — Глибока Інтеграція з ОС","/csharp/system-programming-windows/windows-hooks-services","01.csharp/07.system-programming-windows/20.windows-hooks-services",{"title":376,"path":377,"stem":378},"Системне Програмування C# (Windows) — 07.system-programming-windows","/csharp/system-programming-windows/implementation_plan","01.csharp/07.system-programming-windows/implementation_plan",{"title":380,"icon":132,"path":381,"stem":382,"children":383,"page":59},"Io","/csharp/io","01.csharp/08.io",[384,388,392,396,400],{"title":385,"path":386,"stem":387},"8.1.1. Основи роботи з файловою системою","/csharp/io/file-system-basics","01.csharp/08.io/01.file-system-basics",{"title":389,"path":390,"stem":391},"8.1.2. Потоки (Streams) та Серіалізація Даних","/csharp/io/streams-serialization","01.csharp/08.io/02.streams-serialization",{"title":393,"path":394,"stem":395},"8.2.1. JSON Serialization з System.Text.Json","/csharp/io/json-serialization","01.csharp/08.io/03.json-serialization",{"title":397,"path":398,"stem":399},"8.2.2. XML Serialization та LINQ to XML","/csharp/io/xml-serialization","01.csharp/08.io/04.xml-serialization",{"title":401,"path":402,"stem":403},"8.2.3. Binary Serialization: MessagePack та Protocol Buffers","/csharp/io/binary-serialization","01.csharp/08.io/05.binary-serialization",{"title":405,"icon":132,"path":406,"stem":407,"children":408,"page":59},"Ado Net","/csharp/ado-net","01.csharp/09.ado-net",[409,413,417,421,425,429,433,437,441,445,449,453],{"title":410,"path":411,"stem":412},"9.1. Введення в ADO.NET","/csharp/ado-net/introduction-to-adonet","01.csharp/09.ado-net/01.introduction-to-adonet",{"title":414,"path":415,"stem":416},"9.2. Клас DbConnection — з'єднання з базою даних","/csharp/ado-net/connection","01.csharp/09.ado-net/02.connection",{"title":418,"path":419,"stem":420},"9.3. Клас DbCommand — виконання SQL-запитів","/csharp/ado-net/command-and-queries","01.csharp/09.ado-net/03.command-and-queries",{"title":422,"path":423,"stem":424},"9.4. Клас DbDataReader — ефективне читання даних","/csharp/ado-net/datareader","01.csharp/09.ado-net/04.datareader",{"title":426,"path":427,"stem":428},"9.5. Параметризовані запити та захист від SQL Injection","/csharp/ado-net/parameters-and-sql-injection","01.csharp/09.ado-net/05.parameters-and-sql-injection",{"title":430,"path":431,"stem":432},"9.6. Транзакції в ADO.NET","/csharp/ado-net/transactions","01.csharp/09.ado-net/06.transactions",{"title":434,"path":435,"stem":436},"9.7. DbProviderFactory — провайдер-незалежний код","/csharp/ado-net/provider-factory","01.csharp/09.ado-net/07.provider-factory",{"title":438,"path":439,"stem":440},"9.8. Асинхронний доступ до даних","/csharp/ado-net/async-data-access","01.csharp/09.ado-net/08.async-data-access",{"title":442,"path":443,"stem":444},"9.9. Від'єднаний режим: DataSet, DataTable, DataRow","/csharp/ado-net/disconnected-mode-dataset","01.csharp/09.ado-net/09.disconnected-mode-dataset",{"title":446,"path":447,"stem":448},"9.10. DataAdapter — міст між DataSet та базою даних","/csharp/ado-net/data-adapter","01.csharp/09.ado-net/10.data-adapter",{"title":450,"path":451,"stem":452},"9.11. Data Mapper та Repository: Архітектура доступу до даних","/csharp/ado-net/data-mapper-repository","01.csharp/09.ado-net/11.data-mapper-repository",{"title":454,"path":455,"stem":456},"9.12. Identity Map, Unit of Work та Specification Pattern","/csharp/ado-net/advanced-patterns","01.csharp/09.ado-net/12.advanced-patterns",{"title":458,"icon":255,"path":459,"stem":460,"children":461,"page":59},"Ef Core","/csharp/ef-core","01.csharp/10.ef-core",[462,466,470,474,478,482,486,490,494,498,502,506,510,514,518,522,526,532,538,542,546,550,554,558,562,566,570,574,578,582,586,590,594,598,602,606,610,614,618,622,626,630,634,638,642,646],{"title":463,"path":464,"stem":465},"Що таке ORM? Від SQL до об'єктів","/csharp/ef-core/what-is-orm","01.csharp/10.ef-core/01.what-is-orm",{"title":467,"path":468,"stem":469},"Перший проєкт — від нуля до CRUD","/csharp/ef-core/first-project","01.csharp/10.ef-core/02.first-project",{"title":471,"path":472,"stem":473},"DbContext — Серце EF Core","/csharp/ef-core/dbcontext-deep-dive","01.csharp/10.ef-core/03.dbcontext-deep-dive",{"title":475,"path":476,"stem":477},"Провайдери баз даних — Архітектура та Вибір СУБД","/csharp/ef-core/database-providers","01.csharp/10.ef-core/04.database-providers",{"title":479,"path":480,"stem":481},"Конвенції EF Core — Магія без конфігурації","/csharp/ef-core/conventions","01.csharp/10.ef-core/05.conventions",{"title":483,"path":484,"stem":485},"Fluent API та Data Annotations — Явна конфігурація моделі","/csharp/ef-core/fluent-api-vs-annotations","01.csharp/10.ef-core/06.fluent-api-vs-annotations",{"title":487,"path":488,"stem":489},"Зв'язки — One-to-One та One-to-Many","/csharp/ef-core/relationships-basics","01.csharp/10.ef-core/07.relationships-basics",{"title":491,"path":492,"stem":493},"Зв'язки Advanced — Many-to-Many та Складні Сценарії","/csharp/ef-core/relationships-advanced","01.csharp/10.ef-core/08.relationships-advanced",{"title":495,"path":496,"stem":497},"Властивості — Типи, Конвертери, Компаратори (Частина 1)","/csharp/ef-core/property-configuration-part1","01.csharp/10.ef-core/09.property-configuration-part1",{"title":499,"path":500,"stem":501},"Властивості — Value Comparers, Generators, Shadow Properties (Частина 2)","/csharp/ef-core/property-configuration-part2","01.csharp/10.ef-core/09.property-configuration-part2",{"title":503,"path":504,"stem":505},"Складні типи — Owned Types та Complex Types (Частина 1)","/csharp/ef-core/complex-types-owned-part1","01.csharp/10.ef-core/10.complex-types-owned-part1",{"title":507,"path":508,"stem":509},"Складні типи — Complex Types, Keyless Entities, Порівняння (Частина 2)","/csharp/ef-core/complex-types-owned-part2","01.csharp/10.ef-core/10.complex-types-owned-part2",{"title":511,"path":512,"stem":513},"JSON Columns — Складні дані у JSON (Частина 1)","/csharp/ef-core/json-columns-part1","01.csharp/10.ef-core/11.json-columns-part1",{"title":515,"path":516,"stem":517},"JSON Columns — Value Comparers, Індекси, Провайдери (Частина 2)","/csharp/ef-core/json-columns-part2","01.csharp/10.ef-core/11.json-columns-part2",{"title":519,"path":520,"stem":521},"Успадкування — Абстрактні класи та TPH (Частина 1)","/csharp/ef-core/inheritance-part1","01.csharp/10.ef-core/12.inheritance-part1",{"title":523,"path":524,"stem":525},"Успадкування — TPT, TPC та Порівняння Стратегій (Частина 2)","/csharp/ef-core/inheritance-part2","01.csharp/10.ef-core/12.inheritance-part2",{"title":527,"path":528,"stem":529,"children":530},"Індекси, Обмеження та Схема (Частина 1)","/csharp/ef-core/indexes-constraints-part1","01.csharp/10.ef-core/13.indexes-constraints-part1",[531],{"title":527,"path":528,"stem":529},{"title":533,"path":534,"stem":535,"children":536},"Індекси, Обмеження та Схема (Частина 2)","/csharp/ef-core/indexes-constraints-part2","01.csharp/10.ef-core/13.indexes-constraints-part2",[537],{"title":533,"path":534,"stem":535},{"title":539,"path":540,"stem":541},"Seed Data — Початкові Дані (Частина 1)","/csharp/ef-core/seeding-part1","01.csharp/10.ef-core/14.seeding-part1",{"title":543,"path":544,"stem":545},"Seed Data — SQL-скрипти, Bogus та Стратегії (Частина 2)","/csharp/ef-core/seeding-part2","01.csharp/10.ef-core/14.seeding-part2",{"title":547,"path":548,"stem":549},"Global Query Filters — Глобальні Фільтри (Частина 1)","/csharp/ef-core/global-query-filters-part1","01.csharp/10.ef-core/15.global-query-filters-part1",{"title":551,"path":552,"stem":553},"Global Query Filters — Підводні камені та Інтеграція (Частина 2)","/csharp/ef-core/global-query-filters-part2","01.csharp/10.ef-core/15.global-query-filters-part2",{"title":555,"path":556,"stem":557},"LINQ-запити в EF Core (Частина 1)","/csharp/ef-core/linq-queries-part1","01.csharp/10.ef-core/16.linq-queries-part1",{"title":559,"path":560,"stem":561},"LINQ-запити в EF Core (Частина 2)","/csharp/ef-core/linq-queries-part2","01.csharp/10.ef-core/16.linq-queries-part2",{"title":563,"path":564,"stem":565},"Завантаження Пов'язаних Даних (Частина 1)","/csharp/ef-core/loading-related-data-part1","01.csharp/10.ef-core/17.loading-related-data-part1",{"title":567,"path":568,"stem":569},"Завантаження Пов'язаних Даних (Частина 2)","/csharp/ef-core/loading-related-data-part2","01.csharp/10.ef-core/17.loading-related-data-part2",{"title":571,"path":572,"stem":573},"Raw SQL, Views та Stored Procedures (Частина 1)","/csharp/ef-core/raw-sql-part1","01.csharp/10.ef-core/18.raw-sql-part1",{"title":575,"path":576,"stem":577},"Raw SQL — Stored Procedures, DbFunction та Bulk Operations (Частина 2)","/csharp/ef-core/raw-sql-part2","01.csharp/10.ef-core/18.raw-sql-part2",{"title":579,"path":580,"stem":581},"Продвинуті Запити — Compiled Queries, Bulk та Оптимізація (Частина 1)","/csharp/ef-core/advanced-queries-part1","01.csharp/10.ef-core/19.advanced-queries-part1",{"title":583,"path":584,"stem":585},"Продвинуті Запити — Query Tags, Bulk та Interceptors (Частина 2)","/csharp/ef-core/advanced-queries-part2","01.csharp/10.ef-core/19.advanced-queries-part2",{"title":587,"path":588,"stem":589},"Change Tracker — Відстеження Змін (Частина 1)","/csharp/ef-core/change-tracking-part1","01.csharp/10.ef-core/20.change-tracking-part1",{"title":591,"path":592,"stem":593},"Change Tracker — Графи Об'єктів та Disconnected (Частина 2)","/csharp/ef-core/change-tracking-part2","01.csharp/10.ef-core/20.change-tracking-part2",{"title":595,"path":596,"stem":597},"Збереження Даних та Транзакції (Частина 1)","/csharp/ef-core/saving-data-part1","01.csharp/10.ef-core/21.saving-data-part1",{"title":599,"path":600,"stem":601},"Збереження Даних — Concurrency та Outbox (Частина 2)","/csharp/ef-core/saving-data-part2","01.csharp/10.ef-core/21.saving-data-part2",{"title":603,"path":604,"stem":605},"Конкурентність та Блокування (Частина 1)","/csharp/ef-core/concurrency-part1","01.csharp/10.ef-core/22.concurrency-part1",{"title":607,"path":608,"stem":609},"Конкурентність — Дедлоки та Queue Processing (Частина 2)","/csharp/ef-core/concurrency-part2","01.csharp/10.ef-core/22.concurrency-part2",{"title":611,"path":612,"stem":613},"Міграції в EF Core — Основи (Частина 1)","/csharp/ef-core/migrations-basics-part1","01.csharp/10.ef-core/23.migrations-basics-part1",{"title":615,"path":616,"stem":617},"Міграції в EF Core — Основи (Частина 2)","/csharp/ef-core/migrations-basics-part2","01.csharp/10.ef-core/23.migrations-basics-part2",{"title":619,"path":620,"stem":621},"Міграції — Просунуті Сценарії (Частина 1)","/csharp/ef-core/migrations-advanced-part1","01.csharp/10.ef-core/24.migrations-advanced-part1",{"title":623,"path":624,"stem":625},"Міграції — Просунуті Сценарії (Частина 2)","/csharp/ef-core/migrations-advanced-part2","01.csharp/10.ef-core/24.migrations-advanced-part2",{"title":627,"path":628,"stem":629},"Управління Схемою та Database-First (Частина 1)","/csharp/ef-core/schema-management-part1","01.csharp/10.ef-core/25.schema-management-part1",{"title":631,"path":632,"stem":633},"Управління Схемою та Database-First (Частина 2)","/csharp/ef-core/schema-management-part2","01.csharp/10.ef-core/25.schema-management-part2",{"title":635,"path":636,"stem":637},"Продуктивність EF Core — Основи (Частина 1)","/csharp/ef-core/performance-fundamentals-part1","01.csharp/10.ef-core/26.performance-fundamentals-part1",{"title":639,"path":640,"stem":641},"Interceptors в EF Core (Частина 1)","/csharp/ef-core/interceptors-part1","01.csharp/10.ef-core/29.interceptors-part1",{"title":643,"path":644,"stem":645},"Interceptors в EF Core — Connection, Transaction та Materialization (Частина 2)","/csharp/ef-core/interceptors-part2","01.csharp/10.ef-core/29.interceptors-part2",{"title":647,"path":648,"stem":649},"План вивчення Entity Framework Core — Повний курс","/csharp/ef-core/implementation_plan","01.csharp/10.ef-core/implementation_plan",{"title":651,"icon":652,"path":653,"stem":654,"children":655,"page":59},"ASP.NET","i-devicon-dotnetcore","/csharp/aspnet","01.csharp/11.aspnet",[656,730,791,869,927,941,967,1057,1111,1182,1212,1289],{"title":657,"icon":658,"path":659,"stem":660,"children":661,"page":59},"Minimal API","i-lucide-network","/csharp/aspnet/minimal-api","01.csharp/11.aspnet/01.minimal-api",[662,666,670,674,678,682,686,690,694,698,702,706,710,714,718,722,726],{"title":663,"path":664,"stem":665},"Вступ до ASP.NET та еволюція фреймворку","/csharp/aspnet/minimal-api/introduction","01.csharp/11.aspnet/01.minimal-api/01.introduction",{"title":667,"path":668,"stem":669},"Перший додаток на ASP.NET Core","/csharp/aspnet/minimal-api/first-application","01.csharp/11.aspnet/01.minimal-api/02.first-application",{"title":671,"path":672,"stem":673},"WebApplication, Builder та Dependency Injection","/csharp/aspnet/minimal-api/webapplication-builder","01.csharp/11.aspnet/01.minimal-api/03.webapplication-builder",{"title":675,"path":676,"stem":677},"Конвеєр запитів та Middleware","/csharp/aspnet/minimal-api/request-pipeline-middleware","01.csharp/11.aspnet/01.minimal-api/04.request-pipeline-middleware",{"title":679,"path":680,"stem":681},"Маршрутизація в ASP.NET Core: Основи","/csharp/aspnet/minimal-api/routing-basics","01.csharp/11.aspnet/01.minimal-api/05.routing-basics",{"title":683,"path":684,"stem":685},"Маршрутизація в ASP.NET Core: Розширені можливості","/csharp/aspnet/minimal-api/routing-advanced","01.csharp/11.aspnet/01.minimal-api/06.routing-advanced",{"title":687,"path":688,"stem":689},"Статичні файли в ASP.NET Core","/csharp/aspnet/minimal-api/static-files","01.csharp/11.aspnet/01.minimal-api/07.static-files",{"title":691,"path":692,"stem":693},"Статичні Активи: MapStaticAssets (ASP.NET Core 9.0)","/csharp/aspnet/minimal-api/static-assets","01.csharp/11.aspnet/01.minimal-api/08.static-assets",{"title":695,"path":696,"stem":697},"Конфігурація в ASP.NET Core: Основи","/csharp/aspnet/minimal-api/configuration-fundamentals","01.csharp/11.aspnet/01.minimal-api/09.configuration-fundamentals",{"title":699,"path":700,"stem":701},"Конфігурація: Паттерн Options","/csharp/aspnet/minimal-api/configuration-options","01.csharp/11.aspnet/01.minimal-api/10.configuration-options",{"title":703,"path":704,"stem":705},"Логування в ASP.NET Core: Основи","/csharp/aspnet/minimal-api/logging-basics","01.csharp/11.aspnet/01.minimal-api/11.logging-basics",{"title":707,"path":708,"stem":709},"Логування: Serilog та Middleware","/csharp/aspnet/minimal-api/logging-advanced","01.csharp/11.aspnet/01.minimal-api/12.logging-advanced",{"title":711,"path":712,"stem":713},"Управління станом: HttpContext.Items та Cookies","/csharp/aspnet/minimal-api/state-management","01.csharp/11.aspnet/01.minimal-api/13.state-management",{"title":715,"path":716,"stem":717},"Стан сесії: Sessions","/csharp/aspnet/minimal-api/session-state","01.csharp/11.aspnet/01.minimal-api/14.session-state",{"title":719,"path":720,"stem":721},"Структура проєкту: від хаосу до архітектури","/csharp/aspnet/minimal-api/project-structure","01.csharp/11.aspnet/01.minimal-api/15.project-structure",{"title":723,"path":724,"stem":725},"Scalar у Minimal API: повний проєкт і Fluent OpenAPI","/csharp/aspnet/minimal-api/scalar-openapi-fluent","01.csharp/11.aspnet/01.minimal-api/16.scalar-openapi-fluent",{"title":727,"path":728,"stem":729},"Swagger / Swashbuckle у Minimal API: окремий класичний шлях","/csharp/aspnet/minimal-api/swagger-swashbuckle","01.csharp/11.aspnet/01.minimal-api/17.swagger-swashbuckle",{"title":731,"icon":658,"path":732,"stem":733,"children":734,"page":59},"API","/csharp/aspnet/api","01.csharp/11.aspnet/02.api",[735,739,743,747,751,755,759,763,767,771,775,779,783,787],{"title":736,"path":737,"stem":738},"Що таке API. Клієнт-серверна архітектура","/csharp/aspnet/api/what-is-api","01.csharp/11.aspnet/02.api/01.what-is-api",{"title":740,"path":741,"stem":742},"Формати даних: JSON, XML, TOML та бінарні формати","/csharp/aspnet/api/data-formats","01.csharp/11.aspnet/02.api/02.data-formats",{"title":744,"path":745,"stem":746},"Парадигми API та концепція REST","/csharp/aspnet/api/api-paradigms-rest","01.csharp/11.aspnet/02.api/03.api-paradigms-rest",{"title":748,"path":749,"stem":750},"HTTP-методи, статус-коди та заголовки","/csharp/aspnet/api/http-methods-status-codes","01.csharp/11.aspnet/02.api/04.http-methods-status-codes",{"title":752,"path":753,"stem":754},"Організація HTTP API за принципами REST","/csharp/aspnet/api/rest-organizing","01.csharp/11.aspnet/02.api/05.rest-organizing",{"title":756,"path":757,"stem":758},"Номенклатура URL та CRUD-операції","/csharp/aspnet/api/url-nomenclature-crud","01.csharp/11.aspnet/02.api/06.url-nomenclature-crud",{"title":760,"path":761,"stem":762},"Правила дизайну: іменування та стандарти","/csharp/aspnet/api/api-design-naming","01.csharp/11.aspnet/02.api/07.api-design-naming",{"title":764,"path":765,"stem":766},"Валідація, ліміти та обробка помилок","/csharp/aspnet/api/api-design-validation","01.csharp/11.aspnet/02.api/08.api-design-validation",{"title":768,"path":769,"stem":770},"Обробка помилок у Minimal API","/csharp/aspnet/api/error-handling-http","01.csharp/11.aspnet/02.api/09.error-handling-http",{"title":772,"path":773,"stem":774},"Ідемпотентність та синхронізація стану","/csharp/aspnet/api/idempotency-sync","01.csharp/11.aspnet/02.api/10.idempotency-sync",{"title":776,"path":777,"stem":778},"Пагінація та організація списків","/csharp/aspnet/api/pagination-lists","01.csharp/11.aspnet/02.api/11.pagination-lists",{"title":780,"path":781,"stem":782},"Безпека API, кешування та інтернаціоналізація","/csharp/aspnet/api/security-auth","01.csharp/11.aspnet/02.api/12.security-auth",{"title":784,"path":785,"stem":786},"Процес проєктування API та документування","/csharp/aspnet/api/api-design-process","01.csharp/11.aspnet/02.api/13.api-design-process",{"title":788,"path":789,"stem":790},"OpenAPI: контракт, специфікація та документація API","/csharp/aspnet/api/openapi","01.csharp/11.aspnet/02.api/14.openapi",{"title":792,"icon":793,"path":794,"stem":795,"children":796,"page":59},"Auth","i-lucide-shield-check","/csharp/aspnet/auth","01.csharp/11.aspnet/03.auth",[797,801,805,809,813,817,821,825,829,833,837,841,845,849,853,857,861,865],{"title":798,"path":799,"stem":800},"Основи аутентифікації та авторизації","/csharp/aspnet/auth/auth-fundamentals","01.csharp/11.aspnet/03.auth/01.auth-fundamentals",{"title":802,"path":803,"stem":804},"JWT-аутентифікація","/csharp/aspnet/auth/jwt-authentication","01.csharp/11.aspnet/03.auth/02.jwt-authentication",{"title":806,"path":807,"stem":808},"Авторизація: ролі, політики та resource-based доступ","/csharp/aspnet/auth/authorization-policies","01.csharp/11.aspnet/03.auth/03.authorization-policies",{"title":810,"path":811,"stem":812},"Cookie-аутентифікація та ASP.NET Core Identity","/csharp/aspnet/auth/cookie-auth-identity","01.csharp/11.aspnet/03.auth/04.cookie-auth-identity",{"title":814,"path":815,"stem":816},"JWT + Refresh Tokens (HttpOnly Cookie)","/csharp/aspnet/auth/04b.identity-auth-jwt","01.csharp/11.aspnet/03.auth/04b.identity-auth-jwt",{"title":818,"path":819,"stem":820},"Identity: Підтвердження Email та Скидання Пароля","/csharp/aspnet/auth/identity-email-confirmation","01.csharp/11.aspnet/03.auth/05.identity-email-confirmation",{"title":822,"path":823,"stem":824},"Identity: Двофакторна Аутентифікація (2FA)","/csharp/aspnet/auth/identity-two-factor","01.csharp/11.aspnet/03.auth/06.identity-two-factor",{"title":826,"path":827,"stem":828},"Identity: Внутрішня Архітектура та Кастомізація","/csharp/aspnet/auth/identity-internals","01.csharp/11.aspnet/03.auth/07.identity-internals",{"title":830,"path":831,"stem":832},"OAuth 2.0 та зовнішні провайдери","/csharp/aspnet/auth/oauth-external-providers","01.csharp/11.aspnet/03.auth/08.oauth-external-providers",{"title":834,"path":835,"stem":836},"Безпека на практиці: CORS, HTTPS та захист від атак","/csharp/aspnet/auth/security-hardening","01.csharp/11.aspnet/03.auth/09.security-hardening",{"title":838,"path":839,"stem":840},"Теорія OAuth 2.0: Поняття, Аналогії та Флоу","/csharp/aspnet/auth/oauth-theory","01.csharp/11.aspnet/03.auth/10.oauth-theory",{"title":842,"path":843,"stem":844},"OIDC, OAuth 2.0 та Keycloak в ASP.NET Core","/csharp/aspnet/auth/oidc-keycloak","01.csharp/11.aspnet/03.auth/10.oidc-keycloak",{"title":846,"path":847,"stem":848},"API Keys аутентифікація в ASP.NET Core","/csharp/aspnet/auth/api-keys","01.csharp/11.aspnet/03.auth/11.api-keys",{"title":850,"path":851,"stem":852},"Rate Limiting та Throttling в ASP.NET Core","/csharp/aspnet/auth/rate-limiting","01.csharp/11.aspnet/03.auth/12.rate-limiting",{"title":854,"path":855,"stem":856},"Refresh Token Rotation в ASP.NET Core","/csharp/aspnet/auth/refresh-token-rotation","01.csharp/11.aspnet/03.auth/13.refresh-token-rotation",{"title":858,"path":859,"stem":860},"Certificate Authentication та mTLS в ASP.NET Core","/csharp/aspnet/auth/certificate-auth","01.csharp/11.aspnet/03.auth/14.certificate-auth",{"title":862,"path":863,"stem":864},"RBAC, ABAC та ReBAC в ASP.NET Core","/csharp/aspnet/auth/rbac-abac-rebac","01.csharp/11.aspnet/03.auth/15.rbac-abac-rebac",{"title":866,"path":867,"stem":868},"Multi-tenancy та ізоляція даних в ASP.NET Core","/csharp/aspnet/auth/multi-tenancy","01.csharp/11.aspnet/03.auth/16.multi-tenancy",{"title":870,"icon":871,"path":872,"stem":873,"children":874,"page":59},"Нотифікації","i-lucide-bell","/csharp/aspnet/notifications","01.csharp/11.aspnet/04.notifications",[875,879,883,887,891,895,899,903,907,911,915,919,923],{"title":876,"path":877,"stem":878},"In-App нотифікації через базу даних","/csharp/aspnet/notifications/in-app-database-notifications","01.csharp/11.aspnet/04.notifications/01.in-app-database-notifications",{"title":880,"path":881,"stem":882},"Polling: Регулярний запит оновлень","/csharp/aspnet/notifications/polling","01.csharp/11.aspnet/04.notifications/02.polling",{"title":884,"path":885,"stem":886},"Server-Sent Events: Однострімовий push від сервера","/csharp/aspnet/notifications/server-sent-events","01.csharp/11.aspnet/04.notifications/03.server-sent-events",{"title":888,"path":889,"stem":890},"WebSockets: Двостороннє з'єднання в реальному часі","/csharp/aspnet/notifications/websockets","01.csharp/11.aspnet/04.notifications/04.websockets",{"title":892,"path":893,"stem":894},"SignalR: Абстракція над транспортами реального часу","/csharp/aspnet/notifications/signalr","01.csharp/11.aspnet/04.notifications/05.signalr",{"title":896,"path":897,"stem":898},"Background Services: Фонові задачі в ASP.NET Core","/csharp/aspnet/notifications/background-services","01.csharp/11.aspnet/04.notifications/06.background-services",{"title":900,"path":901,"stem":902},"Web Push нотифікації","/csharp/aspnet/notifications/web-push","01.csharp/11.aspnet/04.notifications/07.web-push",{"title":904,"path":905,"stem":906},"Email нотифікації","/csharp/aspnet/notifications/email-notifications","01.csharp/11.aspnet/04.notifications/08.email-notifications",{"title":908,"path":909,"stem":910},"Порівняння підходів: Як вибрати правильну технологію нотифікацій","/csharp/aspnet/notifications/choosing-the-right-approach","01.csharp/11.aspnet/04.notifications/09.choosing-the-right-approach",{"title":912,"path":913,"stem":914},"Hangfire: Надійне планування фонових задач","/csharp/aspnet/notifications/hangfire","01.csharp/11.aspnet/04.notifications/10.hangfire",{"title":916,"path":917,"stem":918},"Практика: Конвертація зображень у WebP через Hangfire","/csharp/aspnet/notifications/hangfire-image-webp","01.csharp/11.aspnet/04.notifications/11.hangfire-image-webp",{"title":920,"path":921,"stem":922},"Практика: Підготовка відео до HLS-стрімінгу через Hangfire","/csharp/aspnet/notifications/hangfire-video-hls","01.csharp/11.aspnet/04.notifications/12.hangfire-video-hls",{"title":924,"path":925,"stem":926},"Telegram-нотифікації: від одного повідомлення до масових розсилок і мульти-канального підходу","/csharp/aspnet/notifications/telegram-notifications","01.csharp/11.aspnet/04.notifications/13.telegram-notifications",{"title":928,"icon":929,"path":930,"stem":931,"children":932,"page":59},"Інтернаціоналізація","i-lucide-languages","/csharp/aspnet/i18n","01.csharp/11.aspnet/05.i18n",[933,937],{"title":934,"path":935,"stem":936},"Інтернаціоналізація (i18n) у Minimal API: від A до Я","/csharp/aspnet/i18n/internationalization","01.csharp/11.aspnet/05.i18n/01.internationalization",{"title":938,"path":939,"stem":940},"Humanizer: людиномовні рядки у .NET","/csharp/aspnet/i18n/humanizer","01.csharp/11.aspnet/05.i18n/02.humanizer",{"title":942,"icon":943,"path":944,"stem":945,"children":946,"page":59},"Кешування","i-lucide-layers","/csharp/aspnet/caching","01.csharp/11.aspnet/06.caching",[947,951,955,959,963],{"title":948,"path":949,"stem":950},"Огляд кешування: чотири рівні і коли що обирати","/csharp/aspnet/caching/caching","01.csharp/11.aspnet/06.caching/01.caching",{"title":952,"path":953,"stem":954},"IMemoryCache: кеш в оперативній пам'яті","/csharp/aspnet/caching/memory-cache","01.csharp/11.aspnet/06.caching/02.memory-cache",{"title":956,"path":957,"stem":958},"IDistributedCache і Redis: розподілений кеш","/csharp/aspnet/caching/distributed-cache","01.csharp/11.aspnet/06.caching/03.distributed-cache",{"title":960,"path":961,"stem":962},"Response Cache: HTTP-кешування через Cache-Control","/csharp/aspnet/caching/response-cache","01.csharp/11.aspnet/06.caching/04.response-cache",{"title":964,"path":965,"stem":966},"Output Cache: серверний кеш HTTP-відповідей (.NET 7+)","/csharp/aspnet/caching/output-cache","01.csharp/11.aspnet/06.caching/05.output-cache",{"title":968,"icon":969,"path":970,"stem":971,"children":972,"page":59},"Тестування","i-lucide-test-tube","/csharp/aspnet/testing","01.csharp/11.aspnet/07.testing",[973,977,981,985,989,993,997,1001,1005,1009,1013,1017,1021,1025,1029,1033,1037,1041,1045,1049,1053],{"title":974,"path":975,"stem":976},"Що таке тестування? Від інтуїції до науки","/csharp/aspnet/testing/what-is-testing","01.csharp/11.aspnet/07.testing/01.what-is-testing",{"title":978,"path":979,"stem":980},"Піраміда тестування — Стратегія, а не Догма","/csharp/aspnet/testing/testing-pyramid","01.csharp/11.aspnet/07.testing/02.testing-pyramid",{"title":982,"path":983,"stem":984},"Дві Школи Тестування — Лондон проти Детройту","/csharp/aspnet/testing/testing-schools","01.csharp/11.aspnet/07.testing/03.testing-schools",{"title":986,"path":987,"stem":988},"TDD та BDD — Тести як Дизайн-інструмент","/csharp/aspnet/testing/tdd-and-bdd","01.csharp/11.aspnet/07.testing/04.tdd-and-bdd",{"title":990,"path":991,"stem":992},"Що саме тестувати — Техніки аналізу та Циклomatична складність","/csharp/aspnet/testing/what-to-test","01.csharp/11.aspnet/07.testing/05.what-to-test",{"title":994,"path":995,"stem":996},"Тестові Фреймворки — Навіщо вони і що всередині","/csharp/aspnet/testing/test-frameworks","01.csharp/11.aspnet/07.testing/06.test-frameworks",{"title":998,"path":999,"stem":1000},"xUnit — Факти, Теорії та Lifecycle тестів","/csharp/aspnet/testing/xunit-basics","01.csharp/11.aspnet/07.testing/07.xunit-basics",{"title":1002,"path":1003,"stem":1004},"xUnit Advanced — Fixtures, Кастомізація та Розширення","/csharp/aspnet/testing/xunit-advanced","01.csharp/11.aspnet/07.testing/08.xunit-advanced",{"title":1006,"path":1007,"stem":1008},"Moq — Глибоке занурення в мокування","/csharp/aspnet/testing/mocking-with-moq","01.csharp/11.aspnet/07.testing/09.mocking-with-moq",{"title":1010,"path":1011,"stem":1012},"Тестування Баз Даних — EF Core, SQLite та Testcontainers","/csharp/aspnet/testing/database-testing","01.csharp/11.aspnet/07.testing/10.database-testing",{"title":1014,"path":1015,"stem":1016},"Integration Testing — Частина 1 [Теорія та WebApplicationFactory]","/csharp/aspnet/testing/integration-testing","01.csharp/11.aspnet/07.testing/11.integration-testing",{"title":1018,"path":1019,"stem":1020},"Інтеграційне тестування — Практика","/csharp/aspnet/testing/11a.integration-testing-practice","01.csharp/11.aspnet/07.testing/11a.integration-testing-practice",{"title":1022,"path":1023,"stem":1024},"Integration Testing — Частина 2 [Просунуті Сценарії та Testcontainers]","/csharp/aspnet/testing/integration-testing-advanced","01.csharp/11.aspnet/07.testing/12.integration-testing-advanced",{"title":1026,"path":1027,"stem":1028},"Професійний Postman: Колекції, Змінні та GitHub Інтеграція","/csharp/aspnet/testing/postman-professional","01.csharp/11.aspnet/07.testing/13.postman-professional",{"title":1030,"path":1031,"stem":1032},"HttpClient у Тестах Частина 1: Архітектура та MockHttpMessageHandler","/csharp/aspnet/testing/httpclient-testing","01.csharp/11.aspnet/07.testing/14.httpclient-testing",{"title":1034,"path":1035,"stem":1036},"HttpClient у Тестах Частина 2: WireMock.Net та Resilience","/csharp/aspnet/testing/wiremock-net","01.csharp/11.aspnet/07.testing/15.wiremock-net",{"title":1038,"path":1039,"stem":1040},"Патерни та Анти-патерни Тестування: Test Smells","/csharp/aspnet/testing/testing-patterns","01.csharp/11.aspnet/07.testing/16.testing-patterns",{"title":1042,"path":1043,"stem":1044},"Просунуті інструменти: Time, Snapshots та Властивості","/csharp/aspnet/testing/advanced-testing-tools","01.csharp/11.aspnet/07.testing/17.advanced-testing-tools",{"title":1046,"path":1047,"stem":1048},"Тестування Архітектури з NetArchTest","/csharp/aspnet/testing/architecture-testing","01.csharp/11.aspnet/07.testing/18.architecture-testing",{"title":1050,"path":1051,"stem":1052},"Тестування Продуктивності: BenchmarkDotNet, NBomber та k6","/csharp/aspnet/testing/performance-testing","01.csharp/11.aspnet/07.testing/19.performance-testing",{"title":1054,"path":1055,"stem":1056},"Залишок плану для курсу \"Тестування ASP.NET Minimal API\"","/csharp/aspnet/testing/remaining_plan","01.csharp/11.aspnet/07.testing/remaining_plan",{"title":1058,"icon":1059,"path":1060,"stem":1061,"children":1062,"page":59},"Платежі","i-lucide-credit-card","/csharp/aspnet/payments","01.csharp/11.aspnet/08.payments",[1063,1067,1071,1075,1079,1083,1087,1091,1095,1099,1103,1107],{"title":1064,"path":1065,"stem":1066},"Основи платіжної інфраструктури","/csharp/aspnet/payments/payment-fundamentals","01.csharp/11.aspnet/08.payments/01.payment-fundamentals",{"title":1068,"path":1069,"stem":1070},"Методи оплати в Україні","/csharp/aspnet/payments/payment-methods-ukraine","01.csharp/11.aspnet/08.payments/02.payment-methods-ukraine",{"title":1072,"path":1073,"stem":1074},"PCI DSS та безпека платежів","/csharp/aspnet/payments/pci-dss-security","01.csharp/11.aspnet/08.payments/03.pci-dss-security",{"title":1076,"path":1077,"stem":1078},"Архітектура платіжної підсистеми","/csharp/aspnet/payments/payment-architecture","01.csharp/11.aspnet/08.payments/04.payment-architecture",{"title":1080,"path":1081,"stem":1082},"Інтеграція LiqPay (ПриватБанк)","/csharp/aspnet/payments/liqpay-integration","01.csharp/11.aspnet/08.payments/05.liqpay-integration",{"title":1084,"path":1085,"stem":1086},"Інтеграція Monobank Acquiring API","/csharp/aspnet/payments/monobank-acquiring","01.csharp/11.aspnet/08.payments/06.monobank-acquiring",{"title":1088,"path":1089,"stem":1090},"Інтеграція Stripe","/csharp/aspnet/payments/stripe-integration","01.csharp/11.aspnet/08.payments/07.stripe-integration",{"title":1092,"path":1093,"stem":1094},"Webhooks — глибоке занурення","/csharp/aspnet/payments/webhooks-deep-dive","01.csharp/11.aspnet/08.payments/08.webhooks-deep-dive",{"title":1096,"path":1097,"stem":1098},"Підписки та рекурентні платежі","/csharp/aspnet/payments/subscriptions-recurring","01.csharp/11.aspnet/08.payments/09.subscriptions-recurring",{"title":1100,"path":1101,"stem":1102},"Повернення коштів та диспути","/csharp/aspnet/payments/refunds-disputes","01.csharp/11.aspnet/08.payments/10.refunds-disputes",{"title":1104,"path":1105,"stem":1106},"Тестування платіжних інтеграцій","/csharp/aspnet/payments/testing-payments","01.csharp/11.aspnet/08.payments/11.testing-payments",{"title":1108,"path":1109,"stem":1110},"Чекліст виходу в Production","/csharp/aspnet/payments/production-checklist","01.csharp/11.aspnet/08.payments/12.production-checklist",{"title":1112,"icon":1113,"items":1114,"path":1127,"stem":1128,"children":1129,"page":59},"Популярні бібліотеки","lucide:box",[1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126],"01.fluent-validation","02.mapster","03.erroror-result-pattern","04.serilog","05.mediatr","06.polly","07.health-checks","08.feature-management","09.fluent-email","10.quest-pdf","11.bogus","12.humanizer-guard","/csharp/aspnet/libraries","01.csharp/11.aspnet/09.libraries",[1130,1134,1138,1142,1146,1150,1154,1158,1162,1166,1170,1174,1178],{"title":1131,"path":1132,"stem":1133},"Валідація з FluentValidation в ASP.NET Core","/csharp/aspnet/libraries/fluent-validation","01.csharp/11.aspnet/09.libraries/01.fluent-validation",{"title":1135,"path":1136,"stem":1137},"Маппінг об","/csharp/aspnet/libraries/mapster","01.csharp/11.aspnet/09.libraries/02.mapster",{"title":1139,"path":1140,"stem":1141},"Обробка помилок з ErrorOr та Result Pattern в ASP.NET Core","/csharp/aspnet/libraries/erroror-result-pattern","01.csharp/11.aspnet/09.libraries/03.erroror-result-pattern",{"title":1143,"path":1144,"stem":1145},"Структуроване логування з Serilog в ASP.NET Core","/csharp/aspnet/libraries/serilog","01.csharp/11.aspnet/09.libraries/04.serilog",{"title":1147,"path":1148,"stem":1149},"CQRS та Mediator з MediatR в ASP.NET Core","/csharp/aspnet/libraries/mediatr","01.csharp/11.aspnet/09.libraries/05.mediatr",{"title":1151,"path":1152,"stem":1153},"Відмовостійкість з Polly в ASP.NET Core","/csharp/aspnet/libraries/polly","01.csharp/11.aspnet/09.libraries/06.polly",{"title":1155,"path":1156,"stem":1157},"Health Checks в ASP.NET Core","/csharp/aspnet/libraries/health-checks","01.csharp/11.aspnet/09.libraries/07.health-checks",{"title":1159,"path":1160,"stem":1161},"Feature Management та Feature Flags в ASP.NET Core","/csharp/aspnet/libraries/feature-management","01.csharp/11.aspnet/09.libraries/08.feature-management",{"title":1163,"path":1164,"stem":1165},"Відправка Email з FluentEmail в ASP.NET Core","/csharp/aspnet/libraries/fluent-email","01.csharp/11.aspnet/09.libraries/09.fluent-email",{"title":1167,"path":1168,"stem":1169},"Генерація PDF з QuestPDF в ASP.NET Core","/csharp/aspnet/libraries/quest-pdf","01.csharp/11.aspnet/09.libraries/10.quest-pdf",{"title":1171,"path":1172,"stem":1173},"Генерація тестових даних з Bogus в ASP.NET Core","/csharp/aspnet/libraries/bogus","01.csharp/11.aspnet/09.libraries/11.bogus",{"title":1175,"path":1176,"stem":1177},"Humanizer та Guard Clauses в ASP.NET Core","/csharp/aspnet/libraries/humanizer-guard","01.csharp/11.aspnet/09.libraries/12.humanizer-guard",{"title":1179,"path":1180,"stem":1181},"План модуля 10.libraries — Популярні бібліотеки ASP.NET","/csharp/aspnet/libraries/plan","01.csharp/11.aspnet/09.libraries/plan",{"title":1183,"icon":1184,"path":1185,"stem":1186,"children":1187,"page":59},"Razor Pages","i-lucide-layout-template","/csharp/aspnet/razor-pages","01.csharp/11.aspnet/10.razor-pages",[1188,1192,1196,1200,1204,1208],{"title":1189,"path":1190,"stem":1191},"Від Minimal API до Razor Pages: концептуальний перехід","/csharp/aspnet/razor-pages/from-minimal-api","01.csharp/11.aspnet/10.razor-pages/01.from-minimal-api",{"title":1193,"path":1194,"stem":1195},"PageModel: логіка сторінки Razor Pages","/csharp/aspnet/razor-pages/page-model","01.csharp/11.aspnet/10.razor-pages/02.page-model",{"title":1197,"path":1198,"stem":1199},"Razor синтаксис: шаблонізатор у .cshtml","/csharp/aspnet/razor-pages/razor-syntax","01.csharp/11.aspnet/10.razor-pages/03.razor-syntax",{"title":1201,"path":1202,"stem":1203},"Tag Helpers: типізований HTML","/csharp/aspnet/razor-pages/tag-helpers","01.csharp/11.aspnet/10.razor-pages/04.tag-helpers",{"title":1205,"path":1206,"stem":1207},"Форми і валідація: повний цикл обробки даних","/csharp/aspnet/razor-pages/forms-validation","01.csharp/11.aspnet/10.razor-pages/05.forms-validation",{"title":1209,"path":1210,"stem":1211},"Практичний проєкт: TaskManager на Razor Pages","/csharp/aspnet/razor-pages/project-task-manager","01.csharp/11.aspnet/10.razor-pages/06.project-task-manager",{"title":1213,"path":1214,"stem":1215,"children":1216,"page":59},"ASP.NET Core MVC","/csharp/aspnet/mvc","01.csharp/11.aspnet/11.mvc",[1217,1221,1225,1229,1233,1237,1241,1245,1249,1253,1257,1261,1265,1269,1273,1277,1281,1285],{"title":1218,"path":1219,"stem":1220},"Патерн MVC: архітектура, що змінила веб","/csharp/aspnet/mvc/mvc-pattern","01.csharp/11.aspnet/11.mvc/01.mvc-pattern",{"title":1222,"path":1223,"stem":1224},"Від Razor Pages до MVC: концептуальний перехід","/csharp/aspnet/mvc/from-razor-pages","01.csharp/11.aspnet/11.mvc/02.from-razor-pages",{"title":1226,"path":1227,"stem":1228},"Controllers та Actions: серце MVC","/csharp/aspnet/mvc/controllers-actions","01.csharp/11.aspnet/11.mvc/03.controllers-actions",{"title":1230,"path":1231,"stem":1232},"Маршрутизація в MVC: Convention vs Attribute Routing","/csharp/aspnet/mvc/routing-mvc","01.csharp/11.aspnet/11.mvc/04.routing-mvc",{"title":1234,"path":1235,"stem":1236},"Model Binding: від HTTP до C#","/csharp/aspnet/mvc/model-binding","01.csharp/11.aspnet/11.mvc/05.model-binding",{"title":1238,"path":1239,"stem":1240},"Views, ViewData, ViewBag, TempData і ViewModel","/csharp/aspnet/mvc/views-viewdata-tempdata","01.csharp/11.aspnet/11.mvc/06.views-viewdata-tempdata",{"title":1242,"path":1243,"stem":1244},"Filters: аспектно-орієнтоване програмування в MVC","/csharp/aspnet/mvc/filters","01.csharp/11.aspnet/11.mvc/07.filters",{"title":1246,"path":1247,"stem":1248},"Areas: структурування великих застосунків","/csharp/aspnet/mvc/areas","01.csharp/11.aspnet/11.mvc/08.areas",{"title":1250,"path":1251,"stem":1252},"View Components: повторювані незалежні блоки UI","/csharp/aspnet/mvc/view-components","01.csharp/11.aspnet/11.mvc/09.view-components",{"title":1254,"path":1255,"stem":1256},"Display та Editor Templates","/csharp/aspnet/mvc/display-editor-templates","01.csharp/11.aspnet/11.mvc/10.display-editor-templates",{"title":1258,"path":1259,"stem":1260},"Валідація: IValidatableObject та FluentValidation","/csharp/aspnet/mvc/validation-advanced","01.csharp/11.aspnet/11.mvc/11.validation-advanced",{"title":1262,"path":1263,"stem":1264},"HTMX: інтерактивність через HTML-атрибути","/csharp/aspnet/mvc/htmx","01.csharp/11.aspnet/11.mvc/12.htmx",{"title":1266,"path":1267,"stem":1268},"HTMX у ASP.NET Core MVC: серверна інтеграція","/csharp/aspnet/mvc/ajax-htmx-mvc","01.csharp/11.aspnet/11.mvc/13.ajax-htmx-mvc",{"title":1270,"path":1271,"stem":1272},"Практичний проєкт: Каталог товарів з HTMX","/csharp/aspnet/mvc/htmx-project","01.csharp/11.aspnet/11.mvc/14.htmx-project",{"title":1274,"path":1275,"stem":1276},"Завантаження та обробка файлів","/csharp/aspnet/mvc/file-upload","01.csharp/11.aspnet/11.mvc/15.file-upload",{"title":1278,"path":1279,"stem":1280},"Глобалізація та Локалізація MVC","/csharp/aspnet/mvc/globalization-localization","01.csharp/11.aspnet/11.mvc/16.globalization-localization",{"title":1282,"path":1283,"stem":1284},"Підсумковий проєкт: Блог-платформа","/csharp/aspnet/mvc/mvc-project","01.csharp/11.aspnet/11.mvc/17.mvc-project",{"title":1286,"path":1287,"stem":1288},"План курсу: ASP.NET Core MVC","/csharp/aspnet/mvc/plan","01.csharp/11.aspnet/11.mvc/plan",{"title":1290,"path":1291,"stem":1292,"children":1293,"page":59},"Web Api","/csharp/aspnet/web-api","01.csharp/11.aspnet/12.web-api",[1294,1298,1302,1306,1310,1314,1318,1322,1326,1330,1334,1338,1342],{"title":1295,"path":1296,"stem":1297},"Від Minimal API до Controller-based API","/csharp/aspnet/web-api/from-minimal-api-to-controllers","01.csharp/11.aspnet/12.web-api/01.from-minimal-api-to-controllers",{"title":1299,"path":1300,"stem":1301},"ControllerBase, ActionResult\u003CT> та Response Types","/csharp/aspnet/web-api/controller-base-actionresult","01.csharp/11.aspnet/12.web-api/02.controller-base-actionresult",{"title":1303,"path":1304,"stem":1305},"Content Negotiation - JSON, XML та власні форматери","/csharp/aspnet/web-api/content-negotiation","01.csharp/11.aspnet/12.web-api/03.content-negotiation",{"title":1307,"path":1308,"stem":1309},"Версіонування API","/csharp/aspnet/web-api/api-versioning","01.csharp/11.aspnet/12.web-api/04.api-versioning",{"title":1311,"path":1312,"stem":1313},"ProblemDetails та структурована обробка помилок","/csharp/aspnet/web-api/problemdetails-error-handling","01.csharp/11.aspnet/12.web-api/05.problemdetails-error-handling",{"title":1315,"path":1316,"stem":1317},"Фільтри у Web API контексті","/csharp/aspnet/web-api/filters-for-api","01.csharp/11.aspnet/12.web-api/06.filters-for-api",{"title":1319,"path":1320,"stem":1321},"Пагінація, фільтрація та сортування","/csharp/aspnet/web-api/pagination-filtering-sorting","01.csharp/11.aspnet/12.web-api/07.pagination-filtering-sorting",{"title":1323,"path":1324,"stem":1325},"HATEOAS та Resource Expansion","/csharp/aspnet/web-api/hateoas-resource-expansion","01.csharp/11.aspnet/12.web-api/08.hateoas-resource-expansion",{"title":1327,"path":1328,"stem":1329},"Гібридна архітектура - Minimal API + Controllers","/csharp/aspnet/web-api/minimal-api-vs-controllers-hybrid","01.csharp/11.aspnet/12.web-api/09.minimal-api-vs-controllers-hybrid",{"title":1331,"path":1332,"stem":1333},"Документація API - Swashbuckle, NSwag та генерація клієнтів","/csharp/aspnet/web-api/api-documentation-generation","01.csharp/11.aspnet/12.web-api/10.api-documentation-generation",{"title":1335,"path":1336,"stem":1337},"Health Checks та моніторинг API","/csharp/aspnet/web-api/health-checks-monitoring","01.csharp/11.aspnet/12.web-api/11.health-checks-monitoring",{"title":1339,"path":1340,"stem":1341},"Підсумковий проєкт - Production-Ready REST API","/csharp/aspnet/web-api/web-api-project","01.csharp/11.aspnet/12.web-api/12.web-api-project",{"title":1343,"path":1344,"stem":1345},"План курсу: ASP.NET Core Web API (Controllers)","/csharp/aspnet/web-api/plan","01.csharp/11.aspnet/12.web-api/plan",{"title":1347,"icon":1348,"path":1349,"stem":1350,"children":1351,"page":59},"Desktop UI","i-lucide-app-window","/csharp/desktop-ui","01.csharp/12.desktop-ui",[1352,1356,1360,1364,1368,1372,1376,1380,1384,1388,1392,1396,1400,1404,1408,1412,1416,1420,1424,1428,1432,1436,1440,1444,1448,1452,1456,1460,1464,1468,1472,1476,1480,1484,1488,1492,1496,1500,1504,1508,1512,1516,1520,1524,1528,1532,1536,1540,1544,1548,1552,1556,1560,1564,1568,1572,1576,1580,1584,1588,1592,1596,1600,1604,1608,1612,1616,1620,1624,1628,1632],{"title":1353,"path":1354,"stem":1355},"Що таке десктопна розробка?","/csharp/desktop-ui/what-is-desktop-dev","01.csharp/12.desktop-ui/01.what-is-desktop-dev",{"title":1357,"path":1358,"stem":1359},"Архітектура WPF — як влаштований графічний інтерфейс","/csharp/desktop-ui/wpf-architecture","01.csharp/12.desktop-ui/02.wpf-architecture",{"title":1361,"path":1362,"stem":1363},"Перший WPF-проєкт — від нуля до вікна","/csharp/desktop-ui/first-wpf-app","01.csharp/12.desktop-ui/03.first-wpf-app",{"title":1365,"path":1366,"stem":1367},"Перший Avalonia-проєкт: WPF для всіх платформ","/csharp/desktop-ui/03a.first-avalonia-app","01.csharp/12.desktop-ui/03a.first-avalonia-app",{"title":1369,"path":1370,"stem":1371},"XAML: декларативний інтерфейс","/csharp/desktop-ui/xaml-basics","01.csharp/12.desktop-ui/04.xaml-basics",{"title":1373,"path":1374,"stem":1375},"Fluent UI у WPF — сучасний дизайн Windows 11","/csharp/desktop-ui/04a.wpf-fluent-ui","01.csharp/12.desktop-ui/04a.wpf-fluent-ui",{"title":1377,"path":1378,"stem":1379},"WPF UI — сучасна бібліотека Fluent контролів","/csharp/desktop-ui/04b.wpf-ui-library","01.csharp/12.desktop-ui/04b.wpf-ui-library",{"title":1381,"path":1382,"stem":1383},"HandyControl — велика бібліотека UI контролів для WPF","/csharp/desktop-ui/04c.handycontrol-library","01.csharp/12.desktop-ui/04c.handycontrol-library",{"title":1385,"path":1386,"stem":1387},"Простори імен та ресурси XAML","/csharp/desktop-ui/xaml-namespaces-resources","01.csharp/12.desktop-ui/05.xaml-namespaces-resources",{"title":1389,"path":1390,"stem":1391},"XAML в Avalonia: ключові відмінності від WPF","/csharp/desktop-ui/05a.avalonia-xaml-differences","01.csharp/12.desktop-ui/05a.avalonia-xaml-differences",{"title":1393,"path":1394,"stem":1395},"Розширення розмітки XAML (Markup Extensions)","/csharp/desktop-ui/xaml-markup-extensions","01.csharp/12.desktop-ui/06.xaml-markup-extensions",{"title":1397,"path":1398,"stem":1399},"Панелі Layout: StackPanel, WrapPanel, DockPanel","/csharp/desktop-ui/layout-panels-part1","01.csharp/12.desktop-ui/07.layout-panels-part1",{"title":1401,"path":1402,"stem":1403},"Grid, Canvas, UniformGrid","/csharp/desktop-ui/layout-panels-part2","01.csharp/12.desktop-ui/07.layout-panels-part2",{"title":1405,"path":1406,"stem":1407},"Просунуті техніки Layout","/csharp/desktop-ui/layout-advanced","01.csharp/12.desktop-ui/08.layout-advanced",{"title":1409,"path":1410,"stem":1411},"Адаптивний Layout та найкращі практики","/csharp/desktop-ui/layout-responsive","01.csharp/12.desktop-ui/09.layout-responsive",{"title":1413,"path":1414,"stem":1415},"Layout в Avalonia: відмінності та нові можливості","/csharp/desktop-ui/09a.layout-avalonia","01.csharp/12.desktop-ui/09a.layout-avalonia",{"title":1417,"path":1418,"stem":1419},"Button, Image, ProgressBar та інші базові контроли","/csharp/desktop-ui/basic-controls","01.csharp/12.desktop-ui/10.basic-controls",{"title":1421,"path":1422,"stem":1423},"Контроли в Avalonia: відмінності від WPF","/csharp/desktop-ui/10a.controls-avalonia","01.csharp/12.desktop-ui/10a.controls-avalonia",{"title":1425,"path":1426,"stem":1427},"Текстові контроли — TextBlock, TextBox, RichTextBox","/csharp/desktop-ui/text-controls","01.csharp/12.desktop-ui/11.text-controls",{"title":1429,"path":1430,"stem":1431},"Контроли вибору — CheckBox, RadioButton, ComboBox, ListBox, DatePicker","/csharp/desktop-ui/selection-controls","01.csharp/12.desktop-ui/12.selection-controls",{"title":1433,"path":1434,"stem":1435},"Content Model — GroupBox, Expander, TabControl, StatusBar","/csharp/desktop-ui/content-controls","01.csharp/12.desktop-ui/13.content-controls",{"title":1437,"path":1438,"stem":1439},"UI/UX принципи десктопних застосунків","/csharp/desktop-ui/13a.ui-ux-principles","01.csharp/12.desktop-ui/13a.ui-ux-principles",{"title":1441,"path":1442,"stem":1443},"Dependency Properties — Концепція та Value Resolution","/csharp/desktop-ui/dependency-properties-part1","01.csharp/12.desktop-ui/14.dependency-properties-part1",{"title":1445,"path":1446,"stem":1447},"Avalonia Property System — StyledProperty та DirectProperty","/csharp/desktop-ui/14a.avalonia-property-system","01.csharp/12.desktop-ui/14a.avalonia-property-system",{"title":1449,"path":1450,"stem":1451},"Attached Properties — Властивості без меж","/csharp/desktop-ui/attached-properties","01.csharp/12.desktop-ui/15.attached-properties",{"title":1453,"path":1454,"stem":1455},"Routed Events — Маршрутизація подій у WPF","/csharp/desktop-ui/routed-events","01.csharp/12.desktop-ui/16.routed-events",{"title":1457,"path":1458,"stem":1459},"Data Binding — Від Code-Behind до Декларативності","/csharp/desktop-ui/data-binding-basics-part1","01.csharp/12.desktop-ui/17.data-binding-basics-part1",{"title":1461,"path":1462,"stem":1463},"INotifyPropertyChanged — Живе оновлення UI","/csharp/desktop-ui/data-binding-basics-part2","01.csharp/12.desktop-ui/17.data-binding-basics-part2",{"title":1465,"path":1466,"stem":1467},"Compiled Bindings в Avalonia — Безпека на етапі компіляції","/csharp/desktop-ui/17a.avalonia-compiled-bindings","01.csharp/12.desktop-ui/17a.avalonia-compiled-bindings",{"title":1469,"path":1470,"stem":1471},"Просунутий Data Binding — ElementName, RelativeSource, MultiBinding","/csharp/desktop-ui/data-binding-advanced","01.csharp/12.desktop-ui/18.data-binding-advanced",{"title":1473,"path":1474,"stem":1475},"Value Converters — Перетворення типів даних у Data Binding","/csharp/desktop-ui/value-converters","01.csharp/12.desktop-ui/19.value-converters",{"title":1477,"path":1478,"stem":1479},"Data Templates — Візуалізація об'єктів у WPF","/csharp/desktop-ui/data-templates","01.csharp/12.desktop-ui/20.data-templates",{"title":1481,"path":1482,"stem":1483},"Collections Binding Part 1 — ObservableCollection та ItemsControl","/csharp/desktop-ui/collections-binding-part1","01.csharp/12.desktop-ui/21.collections-binding-part1",{"title":1485,"path":1486,"stem":1487},"Collections Binding Part 2 — ICollectionView, Filtering, Sorting та Virtualization","/csharp/desktop-ui/collections-binding-part2","01.csharp/12.desktop-ui/21.collections-binding-part2",{"title":1489,"path":1490,"stem":1491},"MVVM Pattern — Від Spaghetti Code до архітектури","/csharp/desktop-ui/mvvm-pattern","01.csharp/12.desktop-ui/22.mvvm-pattern",{"title":1493,"path":1494,"stem":1495},"ViewModel Implementation — Від BaseViewModel до валідації","/csharp/desktop-ui/viewmodel-implementation","01.csharp/12.desktop-ui/23.viewmodel-implementation",{"title":1497,"path":1498,"stem":1499},"Commands — Від event handlers до декларативних команд","/csharp/desktop-ui/commands","01.csharp/12.desktop-ui/24.commands",{"title":1501,"path":1502,"stem":1503},"MVVM Toolkit — MVVM без boilerplate через Source Generators","/csharp/desktop-ui/mvvm-toolkit","01.csharp/12.desktop-ui/25.mvvm-toolkit",{"title":1505,"path":1506,"stem":1507},"Messenger Pattern — Комунікація між ViewModel без прямих посилань","/csharp/desktop-ui/messenger-pattern","01.csharp/12.desktop-ui/26.messenger-pattern",{"title":1509,"path":1510,"stem":1511},"Стилі WPF — CSS для десктопу","/csharp/desktop-ui/styles-basics","01.csharp/12.desktop-ui/27.styles-basics",{"title":1513,"path":1514,"stem":1515},"CSS-like стилі Avalonia","/csharp/desktop-ui/27a.avalonia-css-styling","01.csharp/12.desktop-ui/27a.avalonia-css-styling",{"title":1517,"path":1518,"stem":1519},"Control Templates — Частина 1. Концепція та TemplateBinding","/csharp/desktop-ui/control-templates-part1","01.csharp/12.desktop-ui/28.control-templates-part1",{"title":1521,"path":1522,"stem":1523},"Control Templates — Частина 2. Named Parts та ContentPresenter","/csharp/desktop-ui/control-templates-part2","01.csharp/12.desktop-ui/28.control-templates-part2",{"title":1525,"path":1526,"stem":1527},"Control Themes в Avalonia — нова ера стилізації","/csharp/desktop-ui/28a.avalonia-control-themes","01.csharp/12.desktop-ui/28a.avalonia-control-themes",{"title":1529,"path":1530,"stem":1531},"Triggers та Visual State Manager у WPF","/csharp/desktop-ui/triggers-visual-states","01.csharp/12.desktop-ui/29.triggers-visual-states",{"title":1533,"path":1534,"stem":1535},"Pseudo-classes в Avalonia — замість WPF Triggers","/csharp/desktop-ui/29a.avalonia-pseudo-classes","01.csharp/12.desktop-ui/29a.avalonia-pseudo-classes",{"title":1537,"path":1538,"stem":1539},"Теми та ресурсні словники у WPF","/csharp/desktop-ui/resources-themes","01.csharp/12.desktop-ui/30.resources-themes",{"title":1541,"path":1542,"stem":1543},"Avalonia Themes — Fluent Design та система тематизації","/csharp/desktop-ui/30a.avalonia-themes-fluent","01.csharp/12.desktop-ui/30a.avalonia-themes-fluent",{"title":1545,"path":1546,"stem":1547},"Контроли колекцій — глибоке занурення","/csharp/desktop-ui/collection-controls","01.csharp/12.desktop-ui/31.collection-controls",{"title":1549,"path":1550,"stem":1551},"DataGrid — колонки та базове відображення","/csharp/desktop-ui/datagrid-part1","01.csharp/12.desktop-ui/32.datagrid-part1",{"title":1553,"path":1554,"stem":1555},"DataGrid — сортування, фільтрація, редагування","/csharp/desktop-ui/datagrid-part2","01.csharp/12.desktop-ui/32.datagrid-part2",{"title":1557,"path":1558,"stem":1559},"TreeView та GridView","/csharp/desktop-ui/treeview-listview","01.csharp/12.desktop-ui/33.treeview-listview",{"title":1561,"path":1562,"stem":1563},"Меню, Toolbar, ContextMenu, StatusBar","/csharp/desktop-ui/menus-toolbars","01.csharp/12.desktop-ui/34.menus-toolbars",{"title":1565,"path":1566,"stem":1567},"Навігація та керування вікнами. Частина 1: вікна та сторінки","/csharp/desktop-ui/navigation-windows-part1","01.csharp/12.desktop-ui/35.navigation-windows-part1",{"title":1569,"path":1570,"stem":1571},"Навігація та керування вікнами. Частина 2: MVVM-навігація","/csharp/desktop-ui/navigation-windows-part2","01.csharp/12.desktop-ui/35.navigation-windows-part2",{"title":1573,"path":1574,"stem":1575},"Avalonia — Навігація та діалоги","/csharp/desktop-ui/35a.avalonia-navigation-dialogs","01.csharp/12.desktop-ui/35a.avalonia-navigation-dialogs",{"title":1577,"path":1578,"stem":1579},"Діалоги та File Pickers у WPF","/csharp/desktop-ui/dialogs-file-pickers","01.csharp/12.desktop-ui/36.dialogs-file-pickers",{"title":1581,"path":1582,"stem":1583},"UserControl: компонентний підхід у WPF","/csharp/desktop-ui/user-controls","01.csharp/12.desktop-ui/37.user-controls",{"title":1585,"path":1586,"stem":1587},"Custom Controls: Lookless Controls у WPF","/csharp/desktop-ui/custom-controls","01.csharp/12.desktop-ui/38.custom-controls",{"title":1589,"path":1590,"stem":1591},"Avalonia TemplatedControl — Lookless Controls","/csharp/desktop-ui/38a.avalonia-templated-controls","01.csharp/12.desktop-ui/38a.avalonia-templated-controls",{"title":1593,"path":1594,"stem":1595},"Анімації у WPF: Storyboard та Easing Functions","/csharp/desktop-ui/animations-transitions","01.csharp/12.desktop-ui/39.animations-transitions",{"title":1597,"path":1598,"stem":1599},"Анімації в Avalonia","/csharp/desktop-ui/39a.avalonia-animations","01.csharp/12.desktop-ui/39a.avalonia-animations",{"title":1601,"path":1602,"stem":1603},"2D Графіка та Мультимедіа у WPF","/csharp/desktop-ui/media-graphics","01.csharp/12.desktop-ui/40.media-graphics",{"title":1605,"path":1606,"stem":1607},"Dependency Injection у WPF та Avalonia","/csharp/desktop-ui/di-integration","01.csharp/12.desktop-ui/41.di-integration",{"title":1609,"path":1610,"stem":1611},"SQLite та EF Core у десктопних додатках","/csharp/desktop-ui/data-persistence-part1","01.csharp/12.desktop-ui/42.data-persistence-part1",{"title":1613,"path":1614,"stem":1615},"Repository Pattern та Unit of Work","/csharp/desktop-ui/data-persistence-part2","01.csharp/12.desktop-ui/43.data-persistence-part2",{"title":1617,"path":1618,"stem":1619},"Тестування ViewModels","/csharp/desktop-ui/viewmodel-testing","01.csharp/12.desktop-ui/44.viewmodel-testing",{"title":1621,"path":1622,"stem":1623},"Avalonia Headless Testing — тестування UI без вікон","/csharp/desktop-ui/44a.avalonia-headless-testing","01.csharp/12.desktop-ui/44a.avalonia-headless-testing",{"title":1625,"path":1626,"stem":1627},"Кросплатформна розробка з Avalonia","/csharp/desktop-ui/avalonia-cross-platform","01.csharp/12.desktop-ui/45.avalonia-cross-platform",{"title":1629,"path":1630,"stem":1631},"Пакування та розгортання Avalonia додатків","/csharp/desktop-ui/avalonia-packaging-deployment","01.csharp/12.desktop-ui/46.avalonia-packaging-deployment",{"title":1633,"path":1634,"stem":1635},"Розгортання WPF застосунків","/csharp/desktop-ui/wpf-packaging-deployment","01.csharp/12.desktop-ui/47.wpf-packaging-deployment",{"title":1637,"path":1638,"stem":1639},"C# & .NET: The Ultimate Roadmap","/csharp/roadmap","01.csharp/roadmap",{"title":1641,"icon":1642,"path":1643,"stem":1644,"children":1645,"page":59},"C++","i-devicon-cplusplus","/cpp","02.cpp",[1646,1650,1654,1658,1662,1666,1670,1674,1678,1681,1685,1689,1693,1697,1701,1705,1709,1713,1717,1721,1725,1729,1733,1737,1741,1745,1749,1753,1757,1761],{"title":1647,"path":1648,"stem":1649},"Вступ у програмування та алгоритми","/cpp/intro-algorithms","02.cpp/01.intro-algorithms",{"title":1651,"path":1652,"stem":1653},"Code Style: угоди про оформлення коду","/cpp/code-style","02.cpp/02.code-style",{"title":1655,"path":1656,"stem":1657},"Середовище розробки та перший проєкт","/cpp/ide-setup","02.cpp/03.ide-setup",{"title":1659,"path":1660,"stem":1661},"Вивід даних на екран","/cpp/data-output","02.cpp/04.data-output",{"title":1663,"path":1664,"stem":1665},"Типи даних, змінні та константи","/cpp/data-types-variables","02.cpp/05.data-types-variables",{"title":1667,"path":1668,"stem":1669},"Ввід даних з клавіатури","/cpp/data-input","02.cpp/06.data-input",{"title":1671,"path":1672,"stem":1673},"Оператори, перетворення типів та логічні операції","/cpp/operators-type-conversion","02.cpp/07.operators-type-conversion",{"title":1675,"path":1676,"stem":1677},"Цикли","/cpp/loops","02.cpp/08.loops",{"title":32,"path":1679,"stem":1680},"/cpp/arrays","02.cpp/09.arrays",{"title":1682,"path":1683,"stem":1684},"Алгоритми сортування та аналіз складності","/cpp/sorting","02.cpp/10.sorting",{"title":1686,"path":1687,"stem":1688},"Алгоритми пошуку","/cpp/searching","02.cpp/11.searching",{"title":1690,"path":1691,"stem":1692},"Функції: основи","/cpp/functions-basics","02.cpp/12.functions-basics",{"title":1694,"path":1695,"stem":1696},"Функції: прототипи, область видимості та додаткові можливості","/cpp/functions-scope","02.cpp/13.functions-scope",{"title":1698,"path":1699,"stem":1700},"Функції: перевантаження та шаблони","/cpp/functions-overloading-templates","02.cpp/14.functions-overloading-templates",{"title":1702,"path":1703,"stem":1704},"Вказівники: основи","/cpp/pointers-basics","02.cpp/15.pointers-basics",{"title":1706,"path":1707,"stem":1708},"Посилання (References)","/cpp/references","02.cpp/16.references",{"title":1710,"path":1711,"stem":1712},"Вказівники, const і масиви","/cpp/pointers-const-arrays","02.cpp/17.pointers-const-arrays",{"title":1714,"path":1715,"stem":1716},"Адресна арифметика","/cpp/pointer-arithmetic","02.cpp/18.pointer-arithmetic",{"title":1718,"path":1719,"stem":1720},"Динамічна пам'ять","/cpp/dynamic-memory","02.cpp/19.dynamic-memory",{"title":1722,"path":1723,"stem":1724},"Вказівники типу void","/cpp/void-pointers","02.cpp/20.void-pointers",{"title":1726,"path":1727,"stem":1728},"Вказівники на вказівники","/cpp/pointers-to-pointers","02.cpp/21.pointers-to-pointers",{"title":1730,"path":1731,"stem":1732},"Оператор доступу до членів через вказівник (->)","/cpp/member-access-operator","02.cpp/22.member-access-operator",{"title":1734,"path":1735,"stem":1736},"Цикл for-each (Range-based for)","/cpp/foreach-loop","02.cpp/23.foreach-loop",{"title":1738,"path":1739,"stem":1740},"Вказівники на функції","/cpp/function-pointers","02.cpp/24.function-pointers",{"title":1742,"path":1743,"stem":1744},"Лямбда-вирази","/cpp/lambdas","02.cpp/25.lambdas",{"title":1746,"path":1747,"stem":1748},"Лямбда-захоплення","/cpp/lambda-captures","02.cpp/26.lambda-captures",{"title":1750,"path":1751,"stem":1752},"Еліпсис","/cpp/ellipsis","02.cpp/27.ellipsis",{"title":1754,"path":1755,"stem":1756},"Аргументи командного рядка","/cpp/command-line-arguments","02.cpp/28.command-line-arguments",{"title":1758,"path":1759,"stem":1760},"Перерахування (enum)","/cpp/enum","02.cpp/29.enum",{"title":1762,"path":1763,"stem":1764},"План навчання: Курс C++ — Продовження (Статті 29–60+)","/cpp/curriculum-plan","02.cpp/curriculum-plan",{"title":1766,"icon":1767,"path":1768,"stem":1769,"children":1770,"page":59},"JavaScript","i-devicon-javascript","/javascript","03.javascript",[1771,1797,1851,1873,2177,2215],{"title":1772,"icon":1773,"path":1774,"stem":1775,"children":1776,"page":59},"Events","i-lucide-mouse-pointer-click","/javascript/events","03.javascript/01.events",[1777,1781,1785,1789,1793],{"title":1778,"path":1779,"stem":1780},"Вступ до подій браузера","/javascript/events/intro","03.javascript/01.events/01.intro",{"title":1782,"path":1783,"stem":1784},"Бульбашковий механізм (Bubbling) та занурення (Capturing)","/javascript/events/bubbling-capturing","03.javascript/01.events/02.bubbling-capturing",{"title":1786,"path":1787,"stem":1788},"Делегування подій (Event Delegation)","/javascript/events/delegate-events","03.javascript/01.events/03.delegate-events",{"title":1790,"path":1791,"stem":1792},"Типові дії браузера та preventDefault()","/javascript/events/prevent-default","03.javascript/01.events/04.prevent-default",{"title":1794,"path":1795,"stem":1796},"Запуск користувацьких подій (Custom Events)","/javascript/events/custom-events","03.javascript/01.events/05.custom-events",{"title":1798,"icon":1799,"path":1800,"stem":1801,"children":1802,"page":59},"Network","i-lucide-globe","/javascript/network","03.javascript/02.network",[1803,1807,1811,1815,1819,1823,1827,1831,1835,1839,1843,1847],{"title":1804,"path":1805,"stem":1806},"Fetch API - Сучасний підхід до HTTP-запитів","/javascript/network/01-fetch-api","03.javascript/02.network/01-fetch-api",{"title":1808,"path":1809,"stem":1810},"FormData - Робота з формами та файлами","/javascript/network/02-formdata","03.javascript/02.network/02-formdata",{"title":1812,"path":1813,"stem":1814},"Відстеження прогресу завантаження","/javascript/network/03-download-progress","03.javascript/02.network/03-download-progress",{"title":1816,"path":1817,"stem":1818},"Переривання fetch-запитів","/javascript/network/04-abort-requests","03.javascript/02.network/04-abort-requests",{"title":1820,"path":1821,"stem":1822},"CORS - Запити між різними джерелами","/javascript/network/05-cors","03.javascript/02.network/05-cors",{"title":1824,"path":1825,"stem":1826},"Fetch API - Повний довідник опцій","/javascript/network/06-fetch-options","03.javascript/02.network/06-fetch-options",{"title":1828,"path":1829,"stem":1830},"URL Objects - Робота з посиланнями","/javascript/network/07-url-objects","03.javascript/02.network/07-url-objects",{"title":1832,"path":1833,"stem":1834},"XMLHttpRequest - AJAX та низькорівневі запити","/javascript/network/08-xmlhttprequest","03.javascript/02.network/08-xmlhttprequest",{"title":1836,"path":1837,"stem":1838},"Відновлюване завантаження файлів","/javascript/network/09-resumable-upload","03.javascript/02.network/09-resumable-upload",{"title":1840,"path":1841,"stem":1842},"Cookies, document.cookie та світ після \"Cookiepocalypse\"","/javascript/network/10-cookies","03.javascript/02.network/10-cookies",{"title":1844,"path":1845,"stem":1846},"js-cookie: Керування Cookies без Болю","/javascript/network/11-js-cookie","03.javascript/02.network/11-js-cookie",{"title":1848,"path":1849,"stem":1850},"Axios: Потужний HTTP-клієнт для JavaScript","/javascript/network/12-axios","03.javascript/02.network/12-axios",{"title":1852,"icon":1853,"path":1854,"stem":1855,"children":1856,"page":59},"Bom","i-lucide-monitor","/javascript/bom","03.javascript/03.bom",[1857,1861,1865,1869],{"title":1858,"path":1859,"stem":1860},"LocalStorage, SessionStorage та patterns збереження даних","/javascript/bom/01-localstorage","03.javascript/03.bom/01-localstorage",{"title":1862,"path":1863,"stem":1864},"Location Object - Керування адресою сторінки","/javascript/bom/02-location-object","03.javascript/03.bom/02-location-object",{"title":1866,"path":1867,"stem":1868},"History API - Керування історією браузера","/javascript/bom/03-history-api","03.javascript/03.bom/03-history-api",{"title":1870,"path":1871,"stem":1872},"Navigator Object - Ідентифікація та Можливості Пристрою","/javascript/bom/04-navigator-object","03.javascript/03.bom/04-navigator-object",{"title":1874,"icon":1875,"path":1876,"stem":1877,"children":1878},"React","i-devicon-react","/javascript/react","03.javascript/04.react/index",[1879,1880,1884,1888,1892,1896,1959,1994,2146],{"title":1874,"path":1876,"stem":1877},{"title":1881,"path":1882,"stem":1883},"Робота з Формами в React","/javascript/react/react-forms","03.javascript/04.react/01.react-forms",{"title":1885,"path":1886,"stem":1887},"React Hook Form: Професійна Робота з Формами","/javascript/react/react-hook-form","03.javascript/04.react/02.react-hook-form",{"title":1889,"path":1890,"stem":1891},"React Hook Form: Глибоке Розуміння Архітектури та Оптимізації","/javascript/react/react-hook-form-new","03.javascript/04.react/02.react-hook-form-new",{"title":1893,"path":1894,"stem":1895},"Axios та React: Професійна Архітектура Запитів","/javascript/react/data-fetching-axios","03.javascript/04.react/03.data-fetching-axios",{"title":1897,"icon":132,"path":1898,"stem":1899,"children":1900},"Tanstack Query","/javascript/react/tanstack-query","03.javascript/04.react/04.tanstack-query/index",[1901,1903,1907,1911,1915,1919,1923,1927,1931,1935,1939,1943,1947,1951,1955],{"title":1902,"path":1898,"stem":1899},"TanStack Query: Майстерність Керування Станом Сервера",{"title":1904,"path":1905,"stem":1906},"Парадигма Server State: Чому useEffect недостатньо","/javascript/react/tanstack-query/server-state-paradigm","03.javascript/04.react/04.tanstack-query/01.server-state-paradigm",{"title":1908,"path":1909,"stem":1910},"Встановлення та Налаштування: Фундамент","/javascript/react/tanstack-query/installation-and-devtools","03.javascript/04.react/04.tanstack-query/02.installation-and-devtools",{"title":1912,"path":1913,"stem":1914},"Основи Запитів та Магія Ключів","/javascript/react/tanstack-query/query-basics-and-keys","03.javascript/04.react/04.tanstack-query/03.query-basics-and-keys",{"title":1916,"path":1917,"stem":1918},"Синхронізація Даних: Життєвий Цикл Запиту","/javascript/react/tanstack-query/data-synchronization","03.javascript/04.react/04.tanstack-query/04.data-synchronization",{"title":1920,"path":1921,"stem":1922},"Мутації та Інвалідація: Зміна Даних","/javascript/react/tanstack-query/mutations-and-invalidation","03.javascript/04.react/04.tanstack-query/05.mutations-and-invalidation",{"title":1924,"path":1925,"stem":1926},"Оптимістичні Оновлення: Швидше за Світло","/javascript/react/tanstack-query/optimistic-updates","03.javascript/04.react/04.tanstack-query/06.optimistic-updates",{"title":1928,"path":1929,"stem":1930},"Пагінація та Infinite Scroll","/javascript/react/tanstack-query/pagination-and-load-more","03.javascript/04.react/04.tanstack-query/07.pagination-and-load-more",{"title":1932,"path":1933,"stem":1934},"Просунуті Патерни та Оптимізація","/javascript/react/tanstack-query/advanced-patterns","03.javascript/04.react/04.tanstack-query/08.advanced-patterns",{"title":1936,"path":1937,"stem":1938},"Архітектура та Best Practices","/javascript/react/tanstack-query/architecture-and-best-practices","03.javascript/04.react/04.tanstack-query/09.architecture-and-best-practices",{"title":1940,"path":1941,"stem":1942},"Server-Side Rendering (SSR) та Гідратація","/javascript/react/tanstack-query/server-side-rendering","03.javascript/04.react/04.tanstack-query/10.server-side-rendering",{"title":1944,"path":1945,"stem":1946},"Стратегії Тестування","/javascript/react/tanstack-query/testing-strategies","03.javascript/04.react/04.tanstack-query/11.testing-strategies",{"title":1948,"path":1949,"stem":1950},"Аутентифікація та Обробка Помилок","/javascript/react/tanstack-query/authentication-and-errors","03.javascript/04.react/04.tanstack-query/12.authentication-and-errors",{"title":1952,"path":1953,"stem":1954},"React Suspense та Майбутнє","/javascript/react/tanstack-query/react-suspense","03.javascript/04.react/04.tanstack-query/13.react-suspense",{"title":1956,"path":1957,"stem":1958},"Глибоке Занурення в Продуктивність","/javascript/react/tanstack-query/performance-deep-dive","03.javascript/04.react/04.tanstack-query/14.performance-deep-dive",{"title":1960,"icon":1875,"path":1961,"stem":1962,"children":1963},"React Router","/javascript/react/react-router","03.javascript/04.react/05.react-router/index",[1964,1966,1970,1974,1978,1982,1986,1990],{"title":1965,"path":1961,"stem":1962},"React Router: Навігаційна система сучасного вебу",{"title":1967,"path":1968,"stem":1969},"Налаштування та Базовий Роутинг","/javascript/react/react-router/setup-and-basic-routing","03.javascript/04.react/05.react-router/01.setup-and-basic-routing",{"title":1971,"path":1972,"stem":1973},"Динамічна Навігація","/javascript/react/react-router/navigation-and-links","03.javascript/04.react/05.react-router/02.navigation-and-links",{"title":1975,"path":1976,"stem":1977},"Вкладені Маршрути та Макети","/javascript/react/react-router/nested-routes-and-layouts","03.javascript/04.react/05.react-router/03.nested-routes-and-layouts",{"title":1979,"path":1980,"stem":1981},"Динамічні Маршрути та Параметри","/javascript/react/react-router/dynamic-routing","03.javascript/04.react/05.react-router/04.dynamic-routing",{"title":1983,"path":1984,"stem":1985},"Data APIs: Loaders та Actions","/javascript/react/react-router/data-loading","03.javascript/04.react/05.react-router/05.data-loading",{"title":1987,"path":1988,"stem":1989},"Просунуті Патерни","/javascript/react/react-router/advanced-patterns","03.javascript/04.react/05.react-router/06.advanced-patterns",{"title":1991,"path":1992,"stem":1993},"Legacy Routing: Компонентний підхід","/javascript/react/react-router/legacy-routing","03.javascript/04.react/05.react-router/07.legacy-routing",{"title":1995,"icon":132,"path":1996,"stem":1997,"children":1998},"Redux","/javascript/react/redux","03.javascript/04.react/06.redux/index",[1999,2001,2017,2046,2055,2076,2092,2121],{"title":2000,"path":1996,"stem":1997},"Redux: Еволюція управління станом",{"title":14,"icon":15,"path":2002,"stem":2003,"children":2004,"page":59},"/javascript/react/redux/fundamentals","03.javascript/04.react/06.redux/01.fundamentals",[2005,2009,2013],{"title":2006,"path":2007,"stem":2008},"Вступ до State Management","/javascript/react/redux/fundamentals/intro-state-management","03.javascript/04.react/06.redux/01.fundamentals/01.intro-state-management",{"title":2010,"path":2011,"stem":2012},"Філософія Redux та Три Принципи","/javascript/react/redux/fundamentals/redux-philosophy","03.javascript/04.react/06.redux/01.fundamentals/02.redux-philosophy",{"title":2014,"path":2015,"stem":2016},"Чисті функції та Іммутабельність","/javascript/react/redux/fundamentals/pure-functions-immutability","03.javascript/04.react/06.redux/01.fundamentals/03.pure-functions-immutability",{"title":2018,"icon":132,"path":2019,"stem":2020,"children":2021,"page":59},"Classic Redux","/javascript/react/redux/classic-redux","03.javascript/04.react/06.redux/02.classic-redux",[2022,2026,2030,2034,2038,2042],{"title":2023,"path":2024,"stem":2025},"Створення Store (Classic Redux)","/javascript/react/redux/classic-redux/store-setup","03.javascript/04.react/06.redux/02.classic-redux/01.store-setup",{"title":2027,"path":2028,"stem":2029},"Actions, Constants та Action Creators","/javascript/react/redux/classic-redux/actions-constants","03.javascript/04.react/06.redux/02.classic-redux/02.actions-constants",{"title":2031,"path":2032,"stem":2033},"Логіка Reducers","/javascript/react/redux/classic-redux/reducers","03.javascript/04.react/06.redux/02.classic-redux/03.reducers",{"title":2035,"path":2036,"stem":2037},"Комбінування Reducers (Root Reducer)","/javascript/react/redux/classic-redux/data-flow","03.javascript/04.react/06.redux/02.classic-redux/04.data-flow",{"title":2039,"path":2040,"stem":2041},"Підключення до React (React-Redux)","/javascript/react/redux/classic-redux/react-redux-connection","03.javascript/04.react/06.redux/02.classic-redux/05.react-redux-connection",{"title":2043,"path":2044,"stem":2045},"Middleware та Асинхронність (Redux Thunk)","/javascript/react/redux/classic-redux/middleware-thunk","03.javascript/04.react/06.redux/02.classic-redux/06.middleware-thunk",{"title":2047,"icon":132,"path":2048,"stem":2049,"children":2050,"page":59},"Transition To Rtk","/javascript/react/redux/transition-to-rtk","03.javascript/04.react/06.redux/03.transition-to-rtk",[2051],{"title":2052,"path":2053,"stem":2054},"Проблеми класичного Redux","/javascript/react/redux/transition-to-rtk/problems-with-classic","03.javascript/04.react/06.redux/03.transition-to-rtk/01.problems-with-classic",{"title":2056,"icon":132,"path":2057,"stem":2058,"children":2059,"page":59},"Redux Toolkit","/javascript/react/redux/redux-toolkit","03.javascript/04.react/06.redux/04.redux-toolkit",[2060,2064,2068,2072],{"title":2061,"path":2062,"stem":2063},"Налаштування Store з configureStore","/javascript/react/redux/redux-toolkit/configure-store","03.javascript/04.react/06.redux/04.redux-toolkit/01.configure-store",{"title":2065,"path":2066,"stem":2067},"createSlice: Революція в Redux","/javascript/react/redux/redux-toolkit/create-slice","03.javascript/04.react/06.redux/04.redux-toolkit/02.create-slice",{"title":2069,"path":2070,"stem":2071},"Асинхронність з createAsyncThunk","/javascript/react/redux/redux-toolkit/async-thunks","03.javascript/04.react/06.redux/04.redux-toolkit/03.async-thunks",{"title":2073,"path":2074,"stem":2075},"04. Entity Adapter: Керування нормалізованим станом","/javascript/react/redux/redux-toolkit/entity-adapter","03.javascript/04.react/06.redux/04.redux-toolkit/04.entity-adapter",{"title":2077,"icon":92,"path":2078,"stem":2079,"children":2080,"page":59},"Advanced","/javascript/react/redux/advanced","03.javascript/04.react/06.redux/05.advanced",[2081,2085,2089],{"title":2082,"path":2083,"stem":2084},"Мемоізація та Селектори: Повний Гайд по Reselect","/javascript/react/redux/advanced/selectors-reselect","03.javascript/04.react/06.redux/05.advanced/01.selectors-reselect",{"title":2086,"path":2087,"stem":2088},"RTK Query: Архітектура Серверного Кешу","/javascript/react/redux/advanced/rtk-query-intro","03.javascript/04.react/06.redux/05.advanced/02.rtk-query-intro",{"title":1936,"path":2090,"stem":2091},"/javascript/react/redux/advanced/architecture-best-practices","03.javascript/04.react/06.redux/05.advanced/03.architecture-best-practices",{"title":2093,"icon":132,"path":2094,"stem":2095,"children":2096,"page":59},"Project Kanban","/javascript/react/redux/project-kanban","03.javascript/04.react/06.redux/06.project-kanban",[2097,2101,2105,2109,2113,2117],{"title":2098,"path":2099,"stem":2100},"Проєкт: Kanban Board (Trello Clone)","/javascript/react/redux/project-kanban/project-overview","03.javascript/04.react/06.redux/06.project-kanban/01.project-overview",{"title":2102,"path":2103,"stem":2104},"Налаштування та Типізація","/javascript/react/redux/project-kanban/setup-and-types","03.javascript/04.react/06.redux/06.project-kanban/02.setup-and-types",{"title":2106,"path":2107,"stem":2108},"Board Slice: Серце Дошки","/javascript/react/redux/project-kanban/board-slice","03.javascript/04.react/06.redux/06.project-kanban/03.board-slice",{"title":2110,"path":2111,"stem":2112},"Логіка Drag & Drop","/javascript/react/redux/project-kanban/drag-and-drop-logic","03.javascript/04.react/06.redux/06.project-kanban/04.drag-and-drop-logic",{"title":2114,"path":2115,"stem":2116},"Інтеграція з RTK Query","/javascript/react/redux/project-kanban/rtk-query-integration","03.javascript/04.react/06.redux/06.project-kanban/05.rtk-query-integration",{"title":2118,"path":2119,"stem":2120},"Optimistic Updates","/javascript/react/redux/project-kanban/optimistic-updates","03.javascript/04.react/06.redux/06.project-kanban/06.optimistic-updates",{"title":2122,"icon":132,"path":2123,"stem":2124,"children":2125,"page":59},"Testing","/javascript/react/redux/testing","03.javascript/04.react/06.redux/07.testing",[2126,2130,2134,2138,2142],{"title":2127,"path":2128,"stem":2129},"Тестування Redux","/javascript/react/redux/testing/intro-testing","03.javascript/04.react/06.redux/07.testing/01.intro-testing",{"title":2131,"path":2132,"stem":2133},"Тестування Reducers","/javascript/react/redux/testing/testing-reducers","03.javascript/04.react/06.redux/07.testing/02.testing-reducers",{"title":2135,"path":2136,"stem":2137},"Тестування Селекторів","/javascript/react/redux/testing/testing-selectors","03.javascript/04.react/06.redux/07.testing/03.testing-selectors",{"title":2139,"path":2140,"stem":2141},"Тестування Компонентів (Integration)","/javascript/react/redux/testing/testing-components","03.javascript/04.react/06.redux/07.testing/04.testing-components",{"title":2143,"path":2144,"stem":2145},"Тестування Async Thunks","/javascript/react/redux/testing/testing-thunks","03.javascript/04.react/06.redux/07.testing/05.testing-thunks",{"title":2147,"icon":132,"path":2148,"stem":2149,"children":2150},"Ui Libraries","/javascript/react/ui-libraries","03.javascript/04.react/07.ui-libraries/index",[2151,2153,2157,2161,2165,2169,2173],{"title":2152,"path":2148,"stem":2149},"UI Бібліотеки в React",{"title":2154,"path":2155,"stem":2156},"Вступ до UI Бібліотек: Навіщо Винаходити Велосипед Двічі?","/javascript/react/ui-libraries/introduction-to-ui-libraries","03.javascript/04.react/07.ui-libraries/01.introduction-to-ui-libraries",{"title":2158,"path":2159,"stem":2160},"Філософія shadcn/ui: \"Not a Component Library\"","/javascript/react/ui-libraries/shadcn-philosophy","03.javascript/04.react/07.ui-libraries/02.shadcn-philosophy",{"title":2162,"path":2163,"stem":2164},"Установка та Налаштування shadcn/ui","/javascript/react/ui-libraries/shadcn-installation","03.javascript/04.react/07.ui-libraries/03.shadcn-installation",{"title":2166,"path":2167,"stem":2168},"Базові Компоненти shadcn/ui: Фундамент Інтерфейсу","/javascript/react/ui-libraries/shadcn-components-basics","03.javascript/04.react/07.ui-libraries/04.shadcn-components-basics",{"title":2170,"path":2171,"stem":2172},"Компоненти Форм: Побудова Інтерактивних Form","/javascript/react/ui-libraries/shadcn-components-forms","03.javascript/04.react/07.ui-libraries/05.shadcn-components-forms",{"title":2174,"path":2175,"stem":2176},"Складні Компоненти: Dialog, Dropdown, Table та Command","/javascript/react/ui-libraries/shadcn-components-advanced","03.javascript/04.react/07.ui-libraries/06.shadcn-components-advanced",{"title":2178,"icon":2179,"path":2180,"stem":2181,"children":2182,"page":59},"TypeScript","i-devicon-typescript","/javascript/typescript","03.javascript/05.typescript",[2183,2187,2191,2195,2199,2203,2207,2211],{"title":2184,"path":2185,"stem":2186},"TypeScript: Броня для вашого коду","/javascript/typescript/intro-and-basic-types","03.javascript/05.typescript/01.intro-and-basic-types",{"title":2188,"path":2189,"stem":2190},"Майстерність Моделювання Даних: Інтерфейси та Просунуті Типи","/javascript/typescript/interfaces-and-advanced-types","03.javascript/05.typescript/02.interfaces-and-advanced-types",{"title":2192,"path":2193,"stem":2194},"Алхімія Типів: Generics та Utility Types","/javascript/typescript/generics-and-utilities","03.javascript/05.typescript/03.generics-and-utilities",{"title":2196,"path":2197,"stem":2198},"Архітектура та Шаблони: Класи в TypeScript","/javascript/typescript/classes-and-oop","03.javascript/05.typescript/04.classes-and-oop",{"title":2200,"path":2201,"stem":2202},"Продакшн та Екосистема: Advanced Config & Workflow","/javascript/typescript/advanced-patterns-and-config","03.javascript/05.typescript/05.advanced-patterns-and-config",{"title":2204,"path":2205,"stem":2206},"TypeScript у світі React","/javascript/typescript/react-basics","03.javascript/05.typescript/06.react-basics",{"title":2208,"path":2209,"stem":2210},"React + TypeScript: Продвинуті патерни","/javascript/typescript/react-advanced","03.javascript/05.typescript/07.react-advanced",{"title":2212,"path":2213,"stem":2214},"React + TypeScript: Екосистема та бібліотеки","/javascript/typescript/react-ecosystem","03.javascript/05.typescript/08.react-ecosystem",{"title":2216,"path":2217,"stem":2218},"Atomic Design","/javascript/atomic-design","03.javascript/2.atomic-design",{"title":2220,"icon":2221,"path":2222,"stem":2223,"children":2224,"page":59},"Java","i-devicon-java","/java","04.java",[2225,2228,2231,2235,2239,2243,2247],{"title":162,"path":2226,"stem":2227},"/java/data-mapper-part1","04.java/01.data-mapper-part1",{"title":166,"path":2229,"stem":2230},"/java/data-mapper-part2","04.java/02.data-mapper-part2",{"title":2232,"path":2233,"stem":2234},"Service Layer: Організація бізнес-логіки","/java/service-layer","04.java/03.service-layer",{"title":2236,"path":2237,"stem":2238},"Rich Domain Model та State Pattern","/java/rich-domain-model","04.java/04.rich-domain-model",{"title":2240,"path":2241,"stem":2242},"Патерни для складної бізнес-логіки","/java/business-logic-patterns","04.java/05.business-logic-patterns",{"title":2244,"path":2245,"stem":2246},"Обробка помилок та валідація","/java/error-handling-validation","04.java/06.error-handling-validation",{"title":2248,"path":2249,"stem":2250,"children":2251,"page":59},"Проектування баз даних","/java/pr2","04.java/pr2",[2252,2256,2260,2264,2268,2272,2276,2280,2284,2288,2292,2296,2300,2304,2308,2312,2316,2320,2324,2328,2332,2336,2340,2344,2348],{"title":2253,"path":2254,"stem":2255},"Концептуальне моделювання: Мистецтво розуміння предметної області","/java/pr2/conceptual-modeling","04.java/pr2/01.conceptual-modeling",{"title":2257,"path":2258,"stem":2259},"Логічне моделювання: Від бізнес-ідей до структур даних","/java/pr2/logical-modeling","04.java/pr2/02.logical-modeling",{"title":2261,"path":2262,"stem":2263},"Нормалізація: Гігієна даних та боротьба з аномаліями","/java/pr2/normalization","04.java/pr2/03.normalization",{"title":2265,"path":2266,"stem":2267},"Фізична схема: Від абстракції до DDL","/java/pr2/physical-schema","04.java/pr2/04.physical-schema",{"title":2269,"path":2270,"stem":2271},"Архітектурна класифікація таблиць","/java/pr2/table-classification","04.java/pr2/05.table-classification",{"title":2273,"path":2274,"stem":2275},"Database Migrations: Версіонування схеми з Flyway","/java/pr2/database-migrations","04.java/pr2/06.database-migrations",{"title":2277,"path":2278,"stem":2279},"А що, якби це була не реляційна БД?","/java/pr2/beyond-relational","04.java/pr2/07.beyond-relational",{"title":2281,"path":2282,"stem":2283},"Object-Relational Impedance Mismatch: Два світи, що не хочуть дружити","/java/pr2/impedance-mismatch","04.java/pr2/09.impedance-mismatch",{"title":2285,"path":2286,"stem":2287},"JDBC: Перший контакт із базою даних","/java/pr2/jdbc-fundamentals","04.java/pr2/10.jdbc-fundamentals",{"title":2289,"path":2290,"stem":2291},"Якість коду: Spotless, SpotBugs та SonarQube","/java/pr2/10a.code-quality","04.java/pr2/10a.code-quality",{"title":2293,"path":2294,"stem":2295},"Connection Pool: Патерн Object Pool для JDBC-з'єднань","/java/pr2/connection-pool","04.java/pr2/11.connection-pool",{"title":2297,"path":2298,"stem":2299},"Row Data Gateway: Об'єкт як обгортка рядка таблиці","/java/pr2/row-data-gateway","04.java/pr2/12.row-data-gateway",{"title":2301,"path":2302,"stem":2303},"Table Data Gateway: Фасад таблиці як архітектурний відступ","/java/pr2/table-data-gateway","04.java/pr2/13.table-data-gateway",{"title":2305,"path":2306,"stem":2307},"Repository + Data Mapper: Правильна шарова архітектура з JDBC","/java/pr2/repository-data-mapper","04.java/pr2/14.repository-data-mapper",{"title":2309,"path":2310,"stem":2311},"Identity Map: Кешування сутностей у рамках сесії","/java/pr2/identity-map","04.java/pr2/15.identity-map",{"title":2313,"path":2314,"stem":2315},"Unit of Work: Відстеження змін і координація JDBC-транзакцій","/java/pr2/unit-of-work","04.java/pr2/16.unit-of-work",{"title":2317,"path":2318,"stem":2319},"Strategy: Замінювані SQL-стратегії для підтримки різних СУБД","/java/pr2/strategy-sql","04.java/pr2/17.strategy-sql",{"title":2321,"path":2322,"stem":2323},"Proxy: Lazy Loading для One-To-Many колекцій","/java/pr2/proxy-lazy-loading","04.java/pr2/18.proxy-lazy-loading",{"title":2325,"path":2326,"stem":2327},"Generic Repository через Java Reflection: анотації та динамічний SQL","/java/pr2/generic-repository-reflection","04.java/pr2/19.generic-repository-reflection",{"title":2329,"path":2330,"stem":2331},"Specification Pattern: Композиція бізнес-правил для складних запитів","/java/pr2/specification-pattern","04.java/pr2/20.specification-pattern",{"title":2333,"path":2334,"stem":2335},"Розширені можливості Specification Pattern: підзапити, агрегації та гібридний підхід","/java/pr2/20a.advanced-specifications","04.java/pr2/20a.advanced-specifications",{"title":2337,"path":2338,"stem":2339},"Асинхронність у JDBC: Від блокуючих викликів до CompletableFuture","/java/pr2/asynchronous-jdbc","04.java/pr2/21.asynchronous-jdbc",{"title":2341,"path":2342,"stem":2343},"Інтеграційне тестування JDBC-репозиторіїв: Embedded H2 та патерн AAA","/java/pr2/integration-testing-h2","04.java/pr2/22.integration-testing-h2",{"title":2345,"path":2346,"stem":2347},"Testcontainers: Тестування з реальною PostgreSQL у Docker-контейнерах","/java/pr2/integration-testing-testcontainers","04.java/pr2/23.integration-testing-testcontainers",{"title":2349,"path":2350,"stem":2351},"Модуль \"Проектування реляційних баз даних\" для 04.java/pr2","/java/pr2/implementation_plan","04.java/pr2/implementation_plan",{"title":2353,"icon":2354,"path":2355,"stem":2356,"children":2357,"page":59},"Бази даних","i-lucide-database","/databases","06.databases",[2358,2388,2411,2448,2477,2495,2529,2541,2550],{"title":2359,"icon":2360,"path":2361,"stem":2362,"children":2363,"page":59},"Intro","i-lucide-play","/databases/intro","06.databases/01.intro",[2364,2368,2372,2376,2380,2384],{"title":2365,"path":2366,"stem":2367},"Введення в теорію баз даних","/databases/intro/introduction-to-databases","06.databases/01.intro/01.introduction-to-databases",{"title":2369,"path":2370,"stem":2371},"Реляційна модель даних","/databases/intro/relational-model-theory","06.databases/01.intro/02.relational-model-theory",{"title":2373,"path":2374,"stem":2375},"ER-моделювання","/databases/intro/er-modeling","06.databases/01.intro/03.er-modeling",{"title":2377,"path":2378,"stem":2379},"Логічне проектування БД","/databases/intro/logical-schema","06.databases/01.intro/04.logical-schema",{"title":2381,"path":2382,"stem":2383},"Класифікація таблиць","/databases/intro/table-classification","06.databases/01.intro/05.table-classification",{"title":2385,"path":2386,"stem":2387},"PlantUML для баз даних","/databases/intro/plantuml-diagrams","06.databases/01.intro/06.plantuml-diagrams",{"title":2389,"icon":2354,"path":2390,"stem":2391,"children":2392,"page":59},"MS SQL Server Start","/databases/ms-sql-server-start","06.databases/02.ms-sql-server-start",[2393,2397,2403,2407],{"title":2394,"path":2395,"stem":2396},"Типи даних у MS SQL Server","/databases/ms-sql-server-start/data-types","06.databases/02.ms-sql-server-start/01.data-types",{"title":2398,"path":2399,"stem":2400,"children":2401},"Індекси у MS SQL Server","/databases/ms-sql-server-start/sql-indexes","06.databases/02.ms-sql-server-start/02.sql-indexes",[2402],{"title":2398,"path":2399,"stem":2400},{"title":2404,"path":2405,"stem":2406},"Системні бази даних MS SQL Server","/databases/ms-sql-server-start/system-databases","06.databases/02.ms-sql-server-start/03.system-databases",{"title":2408,"path":2409,"stem":2410},"Огляд мови SQL та запитів","/databases/ms-sql-server-start/sql-queries-overview","06.databases/02.ms-sql-server-start/04.sql-queries-overview",{"title":2412,"icon":2354,"path":2413,"stem":2414,"children":2415,"page":59},"SQL","/databases/sql","06.databases/03.sql",[2416,2420,2424,2428,2432,2436,2440,2444],{"title":2417,"path":2418,"stem":2419},"Налаштування демонстраційної бази даних","/databases/sql/sample-database-setup","06.databases/03.sql/00.sample-database-setup",{"title":2421,"path":2422,"stem":2423},"DDL - Створення таблиць (CREATE TABLE)","/databases/sql/ddl-create-table","06.databases/03.sql/01.ddl-create-table",{"title":2425,"path":2426,"stem":2427},"DDL - Зміна та видалення таблиць (ALTER, DROP)","/databases/sql/ddl-alter-drop-table","06.databases/03.sql/02.ddl-alter-drop-table",{"title":2429,"path":2430,"stem":2431},"SELECT запити - Основи","/databases/sql/select-queries-fundamentals","06.databases/03.sql/03.select-queries-fundamentals",{"title":2433,"path":2434,"stem":2435},"SELECT запити - Розширені можливості","/databases/sql/select-queries-advanced","06.databases/03.sql/04.select-queries-advanced",{"title":2437,"path":2438,"stem":2439},"INSERT запити - Додавання даних","/databases/sql/insert-queries","06.databases/03.sql/05.insert-queries",{"title":2441,"path":2442,"stem":2443},"UPDATE та DELETE запити","/databases/sql/update-delete-queries","06.databases/03.sql/06.update-delete-queries",{"title":2445,"path":2446,"stem":2447},"Транзакції в SQL","/databases/sql/transactions","06.databases/03.sql/07.transactions",{"title":2449,"icon":2354,"path":2450,"stem":2451,"children":2452,"page":59},"Multi Table Databases","/databases/multi-table-databases","06.databases/04.multi-table-databases",[2453,2457,2461,2465,2469,2473],{"title":2454,"path":2455,"stem":2456},"Зв'язки та нормалізація БД","/databases/multi-table-databases/relationships-and-normalization","06.databases/04.multi-table-databases/00.relationships-and-normalization",{"title":2458,"path":2459,"stem":2460},"INNER JOIN - З'єднання таблиць","/databases/multi-table-databases/inner-join","06.databases/04.multi-table-databases/01.inner-join",{"title":2462,"path":2463,"stem":2464},"OUTER JOINs - LEFT, RIGHT, FULL","/databases/multi-table-databases/outer-joins","06.databases/04.multi-table-databases/02.outer-joins",{"title":2466,"path":2467,"stem":2468},"CROSS та SELF JOINs","/databases/multi-table-databases/cross-self-joins","06.databases/04.multi-table-databases/03.cross-self-joins",{"title":2470,"path":2471,"stem":2472},"Підзапити (Subqueries)","/databases/multi-table-databases/subqueries","06.databases/04.multi-table-databases/04.subqueries",{"title":2474,"path":2475,"stem":2476},"Агрегації з JOIN","/databases/multi-table-databases/aggregations-with-joins","06.databases/04.multi-table-databases/05.aggregations-with-joins",{"title":2478,"icon":2479,"path":2480,"stem":2481,"children":2482,"page":59},"Aggregate Functions","i-lucide-calculator","/databases/aggregate-functions","06.databases/05.aggregate-functions",[2483,2487,2491],{"title":2484,"path":2485,"stem":2486},"Функції агрегування в MS SQL Server","/databases/aggregate-functions/introduction-aggregate-functions","06.databases/05.aggregate-functions/01.introduction-aggregate-functions",{"title":2488,"path":2489,"stem":2490},"Групування даних в MS SQL Server","/databases/aggregate-functions/grouping-data","06.databases/05.aggregate-functions/02.grouping-data",{"title":2492,"path":2493,"stem":2494},"Підзапити з агрегатними функціями","/databases/aggregate-functions/subqueries-aggregates","06.databases/05.aggregate-functions/03.subqueries-aggregates",{"title":2496,"icon":2497,"path":2498,"stem":2499,"children":2500,"page":59},"Тригери та зберігаємі процедури","i-lucide-database-zap","/databases/triggers-stored-procedures","06.databases/07.triggers-stored-procedures",[2501,2505,2509,2513,2517,2521,2525],{"title":2502,"path":2503,"stem":2504},"DML-тригери","/databases/triggers-stored-procedures/dml-triggers","06.databases/07.triggers-stored-procedures/01.dml-triggers",{"title":2506,"path":2507,"stem":2508},"DDL-тригери","/databases/triggers-stored-procedures/ddl-triggers","06.databases/07.triggers-stored-procedures/02.ddl-triggers",{"title":2510,"path":2511,"stem":2512},"Transact-SQL розширення","/databases/triggers-stored-procedures/transact-sql-extensions","06.databases/07.triggers-stored-procedures/03.transact-sql-extensions",{"title":2514,"path":2515,"stem":2516},"Транзакції","/databases/triggers-stored-procedures/transactions","06.databases/07.triggers-stored-procedures/04.transactions",{"title":2518,"path":2519,"stem":2520},"Зберігаємі процедури","/databases/triggers-stored-procedures/stored-procedures","06.databases/07.triggers-stored-procedures/05.stored-procedures",{"title":2522,"path":2523,"stem":2524},"Користувацькі функції","/databases/triggers-stored-procedures/user-defined-functions","06.databases/07.triggers-stored-procedures/06.user-defined-functions",{"title":2526,"path":2527,"stem":2528},"Безпека баз даних","/databases/triggers-stored-procedures/security","06.databases/07.triggers-stored-procedures/08.security",{"title":2526,"icon":793,"path":2530,"stem":2531,"children":2532,"page":59},"/databases/security","06.databases/08.security",[2533,2537],{"title":2534,"path":2535,"stem":2536},"Вступ до безпеки баз даних","/databases/security/introduction","06.databases/08.security/01.introduction",{"title":2538,"path":2539,"stem":2540},"Системні представлення та метадані","/databases/security/system-views","06.databases/08.security/02.system-views",{"title":2542,"icon":2543,"path":2544,"stem":2545,"children":2546,"page":59},"Резервне копіювання та відновлення","i-lucide-database-backup","/databases/backup-recovery","06.databases/09.backup-recovery",[2547],{"title":2542,"path":2548,"stem":2549},"/databases/backup-recovery/backup-restore","06.databases/09.backup-recovery/01.backup-restore",{"title":2551,"icon":2552,"path":2553,"stem":2554,"children":2555,"page":59},"Повнотекстовий пошук","i-lucide-search","/databases/full-text-search","06.databases/10.full-text-search",[2556],{"title":2551,"path":2557,"stem":2558},"/databases/full-text-search/full-text-search","06.databases/10.full-text-search/01.full-text-search",{"title":2560,"icon":2561,"path":2562,"stem":2563,"children":2564,"page":59},"Tools","i-lucide-wrench","/tools","07.tools",[2565],{"title":2566,"icon":2567,"path":2568,"stem":2569,"children":2570},"Docker","i-simple-icons-docker","/tools/docker","07.tools/01.docker/index",[2571,2573,2577,2581,2585,2589,2593,2597,2601,2605,2609,2613,2617,2621,2625,2629,2633,2637],{"title":2572,"path":2568,"stem":2569},"Docker: від нуля до production",{"title":2574,"path":2575,"stem":2576},"Контейнеризація — від проблеми до рішення","/tools/docker/containerization-concept","07.tools/01.docker/01.containerization-concept",{"title":2578,"path":2579,"stem":2580},"Docker — що це і навіщо?","/tools/docker/docker-what-and-why","07.tools/01.docker/02.docker-what-and-why",{"title":2582,"path":2583,"stem":2584},"Архітектура Docker Engine","/tools/docker/docker-architecture","07.tools/01.docker/03.docker-architecture",{"title":2586,"path":2587,"stem":2588},"Встановлення Docker","/tools/docker/installation","07.tools/01.docker/04.installation",{"title":2590,"path":2591,"stem":2592},"Перший контейнер — docker run","/tools/docker/first-container","07.tools/01.docker/05.first-container",{"title":2594,"path":2595,"stem":2596},"Життєвий цикл контейнера","/tools/docker/container-lifecycle","07.tools/01.docker/06.container-lifecycle",{"title":2598,"path":2599,"stem":2600},"Docker Images — фундаментальні концепції","/tools/docker/docker-images-fundamentals","07.tools/01.docker/07.docker-images-fundamentals",{"title":2602,"path":2603,"stem":2604},"Dockerfile — основи","/tools/docker/dockerfile-basics","07.tools/01.docker/08.dockerfile-basics",{"title":2606,"path":2607,"stem":2608},"Dockerfile — просунуті техніки","/tools/docker/dockerfile-advanced","07.tools/01.docker/09.dockerfile-advanced",{"title":2610,"path":2611,"stem":2612},"Build Context та кешування шарів","/tools/docker/build-context-and-cache","07.tools/01.docker/10.build-context-and-cache",{"title":2614,"path":2615,"stem":2616},"Реєстри Docker-образів","/tools/docker/image-registries","07.tools/01.docker/11.image-registries",{"title":2618,"path":2619,"stem":2620},"Контейнеризація .NET додатків","/tools/docker/dotnet-containerization","07.tools/01.docker/12.dotnet-containerization",{"title":2622,"path":2623,"stem":2624},"Томи та збереження даних","/tools/docker/volumes-and-data","07.tools/01.docker/13.volumes-and-data",{"title":2626,"path":2627,"stem":2628},"Основи мережі в Docker","/tools/docker/networking-basics","07.tools/01.docker/14.networking-basics",{"title":2630,"path":2631,"stem":2632},"Змінні оточення та конфігурація","/tools/docker/environment-and-configuration","07.tools/01.docker/15.environment-and-configuration",{"title":2634,"path":2635,"stem":2636},"Docker Compose — оркестрація контейнерів","/tools/docker/docker-compose-basics","07.tools/01.docker/16.docker-compose-basics",{"title":2638,"path":2639,"stem":2640},"Docker Compose — Multi-Service застосунки","/tools/docker/compose-multi-service","07.tools/01.docker/17.compose-multi-service",{"title":2642,"icon":2643,"path":2644,"stem":2645,"children":2646,"page":59},"Software Engineering","i-lucide-code-2","/software-engineering","09.software-engineering",[2647,2651,2655,2659,2663,2667,2671,2675,2679,2683,2687],{"title":2648,"path":2649,"stem":2650},"1. Аналіз предметної області. Експертні знання та складність","/software-engineering/intro.subdomains","09.software-engineering/01.intro.subdomains",{"title":2652,"path":2653,"stem":2654},"2. Обмежені контексти. Інтеграція обмежених контекстів","/software-engineering/integrating-limited-contexts","09.software-engineering/02.integrating-limited-contexts",{"title":2656,"path":2657,"stem":2658},"3. Реалізація простої бізнес-логіки","/software-engineering/simple","09.software-engineering/03.simple",{"title":2660,"path":2661,"stem":2662},"4. Опрацювання складної бізнес-логіки","/software-engineering/complex-business-logic","09.software-engineering/04.complex-business-logic",{"title":2664,"path":2665,"stem":2666},"5. Моделювання фактора часу. Подієво-орієнтована архітектура.","/software-engineering/modelling-the-time-factor","09.software-engineering/05.modelling-the-time-factor",{"title":2668,"path":2669,"stem":2670},"6. Архітектурні патерни","/software-engineering/architectural-patterns","09.software-engineering/06.architectural-patterns",{"title":2672,"path":2673,"stem":2674},"Паттерни взаємодії","/software-engineering/patterns-of-interaction","09.software-engineering/07.patterns-of-interaction",{"title":2676,"path":2677,"stem":2678},"Евристика проєктування","/software-engineering/design-heuristics","09.software-engineering/08.design-heuristics",{"title":2680,"path":2681,"stem":2682},"Еволюція проєктних рішень","/software-engineering/evolution-of-design-solutions","09.software-engineering/09.evolution-of-design-solutions",{"title":2684,"path":2685,"stem":2686},"EventStorming","/software-engineering/eventstorming","09.software-engineering/10.eventstorming",{"title":2688,"path":2689,"stem":2690},"DDD на практиці","/software-engineering/ddd-in-practice","09.software-engineering/11.ddd-in-practice",{"title":2692,"icon":943,"path":2693,"stem":2694,"children":2695,"page":59},"DDD","/ddd","10.ddd",[2696,2700,2704,2708,2712,2716,2720,2724,2728,2732,2736,2740,2744],{"title":2697,"path":2698,"stem":2699},"Аналіз предметної області","/ddd/domain-analysis","10.ddd/01.domain-analysis",{"title":2701,"path":2702,"stem":2703},"Експертні знання про предметну область","/ddd/domain-expert-knowledge","10.ddd/02.domain-expert-knowledge",{"title":2705,"path":2706,"stem":2707},"Як осмислити складність предметної області","/ddd/managing-domain-complexity","10.ddd/03.managing-domain-complexity",{"title":2709,"path":2710,"stem":2711},"Інтеграція обмежених контекстів","/ddd/bounded-context-integration","10.ddd/04.bounded-context-integration",{"title":2713,"path":2714,"stem":2715},"Реалізація простої бізнес-логіки","/ddd/simple-business-logic","10.ddd/05.simple-business-logic",{"title":2717,"path":2718,"stem":2719},"Обробка складної бізнес-логіки","/ddd/complex-business-logic","10.ddd/06.complex-business-logic",{"title":2721,"path":2722,"stem":2723},"Моделювання фактора часу","/ddd/time-modeling","10.ddd/07.time-modeling",{"title":2725,"path":2726,"stem":2727},"Глава 8. Архітектурні Патерни","/ddd/architectural-patterns","10.ddd/08.architectural-patterns",{"title":2729,"path":2730,"stem":2731},"Глава 9. Патерни Взаємодії","/ddd/interaction-patterns","10.ddd/09.interaction-patterns",{"title":2733,"path":2734,"stem":2735},"Глава 10. Проектні Евристики","/ddd/design-heuristics","10.ddd/10.design-heuristics",{"title":2737,"path":2738,"stem":2739},"Глава 11. Еволюція Проектних Рішень","/ddd/evolution-of-design-decisions","10.ddd/11.evolution-of-design-decisions",{"title":2741,"path":2742,"stem":2743},"Глава 12. EventStorming","/ddd/event-storming","10.ddd/12.event-storming",{"title":2745,"path":2746,"stem":2747},"Глава 13. DDD на Практиці","/ddd/ddd-in-practice","10.ddd/13.ddd-in-practice",{"title":2749,"icon":2750,"path":2751,"stem":2752,"children":2753,"page":59},"Media Streaming","i-lucide-video","/media-streaming","11.media-streaming",[2754,2758,2762,2766,2770,2774,2778],{"title":2755,"path":2756,"stem":2757},"01. Магія Стрімінгу: Що відбувається, коли ви натискаєте \"Play\"","/media-streaming/introduction","11.media-streaming/01.introduction",{"title":2759,"path":2760,"stem":2761},"02. Анатомія Медіа: Кодеки, Контейнери та Стиснення","/media-streaming/audio-video-anatomy","11.media-streaming/02.audio-video-anatomy",{"title":2763,"path":2764,"stem":2765},"03. The Gym: FFmpeg Deep Dive","/media-streaming/ffmpeg-gym","11.media-streaming/03.ffmpeg-gym",{"title":2767,"path":2768,"stem":2769},"04. HLS Protocol: HTTP Live Streaming у Деталях","/media-streaming/hls-protocol","11.media-streaming/04.hls-protocol",{"title":2771,"path":2772,"stem":2773},"05. DASH Protocol: Відкритий Стандарт","/media-streaming/dash-protocol","11.media-streaming/05.dash-protocol",{"title":2775,"path":2776,"stem":2777},"06. Масштабування: CDN та Adaptive Bitrate","/media-streaming/cdn-and-adaptive-bitrate","11.media-streaming/06.cdn-and-adaptive-bitrate",{"title":2779,"path":2780,"stem":2781},"07. Війна із Затримкою (Latency)","/media-streaming/realtime-latency","11.media-streaming/07.realtime-latency",{"title":2783,"icon":2784,"path":2785,"stem":2786,"children":2787,"page":59},"HTML & CSS","i-devicon-html5","/html-css","12.html-css",[2788,2792,2796,2800,2804,2808,2812,2816,2820,2824,2828,2832,2836,2840,2844,2848,2852,2856,2860,2864,2868,2872,2876,2880,2884,2888,2892,2896,2900,2904],{"title":2789,"path":2790,"stem":2791},"Вступ до HTML. Структура документа","/html-css/intro-html-structure","12.html-css/01.intro-html-structure",{"title":2793,"path":2794,"stem":2795},"Форматування тексту в HTML","/html-css/html-text-formatting","12.html-css/02.html-text-formatting",{"title":2797,"path":2798,"stem":2799},"Посилання та зображення в HTML","/html-css/html-links-images","12.html-css/03.html-links-images",{"title":2801,"path":2802,"stem":2803},"Списки та таблиці в HTML","/html-css/html-lists-tables","12.html-css/04.html-lists-tables",{"title":2805,"path":2806,"stem":2807},"Форми в HTML","/html-css/html-forms","12.html-css/05.html-forms",{"title":2809,"path":2810,"stem":2811},"Семантичні елементи HTML5","/html-css/html-semantic-elements","12.html-css/06.html-semantic-elements",{"title":2813,"path":2814,"stem":2815},"Мультимедіа та розширені елементи HTML","/html-css/html-multimedia-advanced","12.html-css/07.html-multimedia-advanced",{"title":2817,"path":2818,"stem":2819},"Мікророзмітка та SEO в HTML","/html-css/html-microdata-seo","12.html-css/08.html-microdata-seo",{"title":2821,"path":2822,"stem":2823},"Вступ до CSS. Селектори та специфічність","/html-css/css-intro-selectors","12.html-css/09.css-intro-selectors",{"title":2825,"path":2826,"stem":2827},"Блокова модель CSS. Відступи. Box Sizing","/html-css/css-box-model","12.html-css/10.css-box-model",{"title":2829,"path":2830,"stem":2831},"Розміри у CSS: повний довідник одиниць і ключових слів","/html-css/10a.css-sizing","12.html-css/10a.css-sizing",{"title":2833,"path":2834,"stem":2835},"Типографіка в CSS. Шрифти та текст","/html-css/css-typography","12.html-css/11.css-typography",{"title":2837,"path":2838,"stem":2839},"Кольори та фони в CSS","/html-css/css-colors-backgrounds","12.html-css/12.css-colors-backgrounds",{"title":2841,"path":2842,"stem":2843},"Тіні та фільтри в CSS","/html-css/12b.css-shadows-filters","12.html-css/12b.css-shadows-filters",{"title":2845,"path":2846,"stem":2847},"CSS Flexbox: Фундамент гнучких макетів","/html-css/css-flexbox-fundamentals","12.html-css/13.css-flexbox-fundamentals",{"title":2849,"path":2850,"stem":2851},"CSS Flexbox: Вирівнювання та Позиціонування","/html-css/css-flexbox-alignment-sizing-and-patterns","12.html-css/14.css-flexbox-alignment-sizing-and-patterns",{"title":2853,"path":2854,"stem":2855},"CSS Grid. Двовимірний макет. Частина 1","/html-css/css-layout-grid","12.html-css/15.css-layout-grid",{"title":2857,"path":2858,"stem":2859},"CSS Grid. Двовимірний макет. Частина 2","/html-css/css-layout-grid-advanced","12.html-css/16.css-layout-grid-advanced",{"title":2861,"path":2862,"stem":2863},"Позиціонування в CSS. Z-index. Stacking Context","/html-css/css-positioning","12.html-css/17.css-positioning",{"title":2865,"path":2866,"stem":2867},"CSS Анімації та Переходи","/html-css/css-animations-transitions","12.html-css/18.css-animations-transitions",{"title":2869,"path":2870,"stem":2871},"Адаптивний дизайн. Media Queries. Частина 1","/html-css/css-responsive-media-queries","12.html-css/19.css-responsive-media-queries",{"title":2873,"path":2874,"stem":2875},"Адаптивний дизайн. Частина 2: clamp(), Container Queries, @layer","/html-css/css-responsive-advanced","12.html-css/20.css-responsive-advanced",{"title":2877,"path":2878,"stem":2879},"CSS Custom Properties. Методології. Сучасний CSS","/html-css/css-variables-methodologies","12.html-css/21.css-variables-methodologies",{"title":2881,"path":2882,"stem":2883},"Сучасний CSS 2023–2025: Нові можливості","/html-css/css-modern-features","12.html-css/22.css-modern-features",{"title":2885,"path":2886,"stem":2887},"CSS Nesting, @layer, @scope та @property: нативний препроцесор","/html-css/22a.css-nesting-modern-syntax","12.html-css/22a.css-nesting-modern-syntax",{"title":2889,"path":2890,"stem":2891},"CSS для форм та інтерактивних станів","/html-css/css-forms-interactive-states","12.html-css/23.css-forms-interactive-states",{"title":2893,"path":2894,"stem":2895},"Доступність у CSS (CSS Accessibility)","/html-css/css-accessibility","12.html-css/24.css-accessibility",{"title":2897,"path":2898,"stem":2899},"CSS-функції та сучасні sizing primitives","/html-css/css-functions-sizing","12.html-css/25.css-functions-sizing",{"title":2901,"path":2902,"stem":2903},"Rendering Pipeline і CSS Performance","/html-css/css-rendering-performance","12.html-css/26.css-rendering-performance",{"title":2905,"path":2906,"stem":2907},"CSS Best Practices: типові ситуації та правильні рішення","/html-css/css-best-practices","12.html-css/27.css-best-practices",{"title":2909,"path":2910,"stem":2911,"children":2912,"page":59},"Tailwind","/tailwind","21.tailwind",[2913,2917,2921,2925,2929,2933,2937,2941],{"title":2914,"path":2915,"stem":2916},"Що таке Tailwind CSS і навіщо він потрібен","/tailwind/tailwind-intro-philosophy","21.tailwind/01.tailwind-intro-philosophy",{"title":2918,"path":2919,"stem":2920},"Встановлення та налаштування Tailwind CSS v4","/tailwind/tailwind-installation-setup","21.tailwind/02.tailwind-installation-setup",{"title":2922,"path":2923,"stem":2924},"Utility-класи: основи та система Tailwind","/tailwind/tailwind-utility-classes-core","21.tailwind/03.tailwind-utility-classes-core",{"title":2926,"path":2927,"stem":2928},"Layout: Flexbox та Grid через Tailwind","/tailwind/tailwind-flexbox-grid","21.tailwind/04.tailwind-flexbox-grid",{"title":2930,"path":2931,"stem":2932},"Кастомізація теми через @theme у Tailwind v4","/tailwind/tailwind-theme-customization","21.tailwind/05.tailwind-theme-customization",{"title":2934,"path":2935,"stem":2936},"Варіанти: hover, focus, responsive, dark mode та нові v4","/tailwind/tailwind-variants-states","21.tailwind/06.tailwind-variants-states",{"title":2938,"path":2939,"stem":2940},"Типографіка та система кольорів у Tailwind v4","/tailwind/tailwind-typography-colors","21.tailwind/07.tailwind-typography-colors",{"title":2942,"path":2943,"stem":2944},"Компоненти та повторюваність: @apply, @utility та патерни","/tailwind/tailwind-components-patterns","21.tailwind/08.tailwind-components-patterns",{"title":2946,"path":2947,"stem":2948},"Showcase Компонентів kostyl.dev","/test-new-components","98.test-new-components",{"id":2950,"title":328,"body":2951,"description":22433,"extension":22434,"links":22435,"meta":22436,"navigation":3115,"path":329,"seo":22437,"stem":330,"__hash__":22438},"docs/01.csharp/07.system-programming-windows/10.concurrent-collections.md",{"type":2952,"value":2953,"toc":22355},"minimark",[2954,2958,2963,2994,3005,3008,3024,3027,3031,3040,3043,3342,3347,3353,3485,3491,3499,3508,3512,3858,3863,3876,3895,3901,3912,3916,4023,4027,4249,4254,4260,4262,4266,4270,4283,4289,4294,4309,4314,4328,4332,4338,4343,4350,4373,4380,4405,4410,4417,4423,4428,4438,4443,4449,4454,4461,4466,4613,4619,4623,4628,4815,4825,4829,4990,4995,5010,5014,5316,5326,5489,5493,5809,5814,6027,6031,6288,6293,6528,6532,6706,6710,7856,7860,7866,7872,8869,8874,8880,8885,8907,8913,8996,9008,9013,9053,9055,9062,9066,9078,9084,9089,9124,9127,9439,9458,9462,10011,10013,10020,10024,10036,10042,10047,10065,10068,10450,10452,10459,10463,10472,10478,10482,10494,10499,10507,10511,10520,10525,10617,10622,10672,10677,10759,10764,10861,10865,10988,10993,10999,11019,11030,11048,11053,11096,11100,11105,11122,11127,11149,11153,11584,11586,11590,11850,11852,11858,11862,11875,11901,11907,11910,12291,12295,12301,12316,12746,12750,13362,13366,13372,13376,13381,13411,13416,13437,13439,13443,13447,13461,13466,13473,13601,13611,13615,13621,13642,13648,14165,14178,14182,14197,14203,14208,14292,14297,14306,14312,14317,14337,14342,14610,14615,14621,14627,14631,14771,14776,14850,14855,14865,14876,14882,14887,14890,14896,14899,14904,14939,14943,14954,15291,15297,15401,15405,16043,16052,16452,16461,16464,17063,17067,17081,17088,17100,17354,17359,17374,17379,17390,17395,17492,17496,18245,18250,18276,18280,18397,18401,18500,18502,18506,18509,18513,18518,18894,18899,18905,18914,18918,18923,18929,18937,18941,18946,18952,18962,18966,18971,18977,18984,18988,18993,18999,19004,19008,19068,19070,19074,19077,19419,19423,19426,19430,19611,19615,19826,19831,19886,19888,19892,19896,19902,19907,19940,19945,20446,20460,20462,20466,20471,20475,20494,20498,21122,21138,21140,21144,21149,21153,21176,21180,22229,22233,22254,22256,22260,22263,22267,22288,22292,22306,22311,22335,22346,22351],[2955,2956,328],"h1",{"id":2957},"concurrent-та-immutable-collections",[2959,2960,2962],"h2",{"id":2961},"вступ-проблема-thread-safety-у-колекціях","Вступ: Проблема Thread-Safety у Колекціях",[2964,2965,2966,2967,2971,2972,2975,2976,2980,2981,2971,2984,2971,2987,2990,2991,2993],"p",{},"Ви вже знаєте як синхронізувати доступ до простих змінних через ",[2968,2969,2970],"code",{},"lock",", ",[2968,2973,2974],{},"Interlocked"," та інші примітиви. Але що робити з ",[2977,2978,2979],"strong",{},"колекціями"," — ",[2968,2982,2983],{},"List\u003CT>",[2968,2985,2986],{},"Dictionary\u003CK,V>",[2968,2988,2989],{},"Queue\u003CT>","? Чи можна просто обгорнути їх у ",[2968,2992,2970],{}," і забути про проблеми?",[2964,2995,2996,2997,3000,3001,3004],{},"Відповідь: ",[2977,2998,2999],{},"можна, але це неефективно",". .NET надає спеціалізовані ",[2977,3002,3003],{},"concurrent collections"," що оптимізовані для багатопотокового доступу і працюють набагато швидше ніж \"колекція + lock\".",[2964,3006,3007],{},"У цій темі ми розглянемо:",[3009,3010,3011,3015,3018,3021],"ul",{},[3012,3013,3014],"li",{},"Чому звичайні колекції небезпечні у багатопотоковому коді",[3012,3016,3017],{},"Як працюють concurrent collections під капотом",[3012,3019,3020],{},"Коли використовувати concurrent vs immutable collections",[3012,3022,3023],{},"Практичні patterns для producer-consumer сценаріїв",[3025,3026],"hr",{},[2959,3028,3030],{"id":3029},"чому-звичайні-колекції-не-thread-safe","Чому Звичайні Колекції Не Thread-Safe?",[3032,3033,3035,3036],"h3",{"id":3034},"демонстрація-list-corruption","Демонстрація: List",[3037,3038,3039],"t",{}," Corruption",[2964,3041,3042],{},"Почнемо з простого експерименту:",[3044,3045,3052],"pre",{"className":3046,"code":3047,"filename":3048,"language":3049,"meta":3050,"style":3051},"language-csharp shiki shiki-themes light-plus dark-plus dark-plus","using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\n\nvar list = new List\u003Cint>();\n\n// 10 потоків одночасно додають по 1000 елементів\nParallel.For(0, 10, i =>\n{\n    for (int j = 0; j \u003C 1000; j++)\n    {\n        list.Add(i * 1000 + j);  // ← НЕ thread-safe!\n    }\n});\n\nConsole.WriteLine($\"Expected: 10000, Actual: {list.Count}\");\n// Типовий результат: 8500-9800 (втрачено елементи!)\n\n// Ще гірше: можлива IndexOutOfRangeException або навіть crash!\n","ListCorruption.cs","csharp","showLineNumbers","",[2968,3053,3054,3071,3091,3110,3117,3146,3151,3158,3190,3196,3233,3239,3270,3276,3282,3287,3325,3331,3336],{"__ignoreMap":3051},[3055,3056,3059,3063,3067],"span",{"class":3057,"line":3058},"line",1,[3055,3060,3062],{"class":3061},"sCDza","using",[3055,3064,3066],{"class":3065},"sN1BT"," System",[3055,3068,3070],{"class":3069},"sHH4Y",";\n",[3055,3072,3074,3076,3078,3081,3084,3086,3089],{"class":3057,"line":3073},2,[3055,3075,3062],{"class":3061},[3055,3077,3066],{"class":3065},[3055,3079,3080],{"class":3069},".",[3055,3082,3083],{"class":3065},"Collections",[3055,3085,3080],{"class":3069},[3055,3087,3088],{"class":3065},"Generic",[3055,3090,3070],{"class":3069},[3055,3092,3094,3096,3098,3100,3103,3105,3108],{"class":3057,"line":3093},3,[3055,3095,3062],{"class":3061},[3055,3097,3066],{"class":3065},[3055,3099,3080],{"class":3069},[3055,3101,3102],{"class":3065},"Threading",[3055,3104,3080],{"class":3069},[3055,3106,3107],{"class":3065},"Tasks",[3055,3109,3070],{"class":3069},[3055,3111,3113],{"class":3057,"line":3112},4,[3055,3114,3116],{"emptyLinePlaceholder":3115},true,"\n",[3055,3118,3120,3124,3128,3131,3134,3137,3140,3143],{"class":3057,"line":3119},5,[3055,3121,3123],{"class":3122},"su1O8","var",[3055,3125,3127],{"class":3126},"siwwj"," list",[3055,3129,3130],{"class":3069}," = ",[3055,3132,3133],{"class":3122},"new",[3055,3135,3136],{"class":3065}," List",[3055,3138,3139],{"class":3069},"\u003C",[3055,3141,3142],{"class":3122},"int",[3055,3144,3145],{"class":3069},">();\n",[3055,3147,3149],{"class":3057,"line":3148},6,[3055,3150,3116],{"emptyLinePlaceholder":3115},[3055,3152,3154],{"class":3057,"line":3153},7,[3055,3155,3157],{"class":3156},"spJ8K","// 10 потоків одночасно додають по 1000 елементів\n",[3055,3159,3161,3164,3166,3170,3173,3177,3179,3182,3184,3187],{"class":3057,"line":3160},8,[3055,3162,3163],{"class":3126},"Parallel",[3055,3165,3080],{"class":3069},[3055,3167,3169],{"class":3168},"s8Opu","For",[3055,3171,3172],{"class":3069},"(",[3055,3174,3176],{"class":3175},"sJj4R","0",[3055,3178,2971],{"class":3069},[3055,3180,3181],{"class":3175},"10",[3055,3183,2971],{"class":3069},[3055,3185,3186],{"class":3126},"i",[3055,3188,3189],{"class":3069}," =>\n",[3055,3191,3193],{"class":3057,"line":3192},9,[3055,3194,3195],{"class":3069},"{\n",[3055,3197,3199,3202,3205,3207,3210,3212,3214,3217,3220,3223,3226,3228,3230],{"class":3057,"line":3198},10,[3055,3200,3201],{"class":3061},"    for",[3055,3203,3204],{"class":3069}," (",[3055,3206,3142],{"class":3122},[3055,3208,3209],{"class":3126}," j",[3055,3211,3130],{"class":3069},[3055,3213,3176],{"class":3175},[3055,3215,3216],{"class":3069},"; ",[3055,3218,3219],{"class":3126},"j",[3055,3221,3222],{"class":3069}," \u003C ",[3055,3224,3225],{"class":3175},"1000",[3055,3227,3216],{"class":3069},[3055,3229,3219],{"class":3126},[3055,3231,3232],{"class":3069},"++)\n",[3055,3234,3236],{"class":3057,"line":3235},11,[3055,3237,3238],{"class":3069},"    {\n",[3055,3240,3242,3245,3247,3250,3252,3254,3257,3259,3262,3264,3267],{"class":3057,"line":3241},12,[3055,3243,3244],{"class":3126},"        list",[3055,3246,3080],{"class":3069},[3055,3248,3249],{"class":3168},"Add",[3055,3251,3172],{"class":3069},[3055,3253,3186],{"class":3126},[3055,3255,3256],{"class":3069}," * ",[3055,3258,3225],{"class":3175},[3055,3260,3261],{"class":3069}," + ",[3055,3263,3219],{"class":3126},[3055,3265,3266],{"class":3069},");  ",[3055,3268,3269],{"class":3156},"// ← НЕ thread-safe!\n",[3055,3271,3273],{"class":3057,"line":3272},13,[3055,3274,3275],{"class":3069},"    }\n",[3055,3277,3279],{"class":3057,"line":3278},14,[3055,3280,3281],{"class":3069},"});\n",[3055,3283,3285],{"class":3057,"line":3284},15,[3055,3286,3116],{"emptyLinePlaceholder":3115},[3055,3288,3290,3293,3295,3298,3300,3304,3308,3311,3313,3316,3319,3322],{"class":3057,"line":3289},16,[3055,3291,3292],{"class":3126},"Console",[3055,3294,3080],{"class":3069},[3055,3296,3297],{"class":3168},"WriteLine",[3055,3299,3172],{"class":3069},[3055,3301,3303],{"class":3302},"sbdoH","$\"Expected: 10000, Actual: ",[3055,3305,3307],{"class":3306},"sD7JJ","{",[3055,3309,3310],{"class":3126},"list",[3055,3312,3080],{"class":3306},[3055,3314,3315],{"class":3126},"Count",[3055,3317,3318],{"class":3306},"}",[3055,3320,3321],{"class":3302},"\"",[3055,3323,3324],{"class":3069},");\n",[3055,3326,3328],{"class":3057,"line":3327},17,[3055,3329,3330],{"class":3156},"// Типовий результат: 8500-9800 (втрачено елементи!)\n",[3055,3332,3334],{"class":3057,"line":3333},18,[3055,3335,3116],{"emptyLinePlaceholder":3115},[3055,3337,3339],{"class":3057,"line":3338},19,[3055,3340,3341],{"class":3156},"// Ще гірше: можлива IndexOutOfRangeException або навіть crash!\n",[2964,3343,3344],{},[2977,3345,3346],{},"Що пішло не так?",[2964,3348,3349,3352],{},[2968,3350,3351],{},"List\u003CT>.Add()"," виконує наступні кроки:",[3044,3354,3356],{"className":3046,"code":3355,"language":3049,"meta":3051,"style":3051},"// Спрощений псевдокод List\u003CT>.Add():\npublic void Add(T item)\n{\n    if (_size == _items.Length)  // 1. Перевірка чи потрібно розширити масив\n    {\n        EnsureCapacity(_size + 1);  // 2. Розширення (створення нового масиву)\n    }\n\n    _items[_size] = item;  // 3. Запис елемента\n    _size++;               // 4. Інкремент розміру\n}\n",[2968,3357,3358,3363,3385,3389,3416,3420,3439,3443,3447,3469,3480],{"__ignoreMap":3051},[3055,3359,3360],{"class":3057,"line":3058},[3055,3361,3362],{"class":3156},"// Спрощений псевдокод List\u003CT>.Add():\n",[3055,3364,3365,3368,3371,3374,3376,3379,3382],{"class":3057,"line":3073},[3055,3366,3367],{"class":3122},"public",[3055,3369,3370],{"class":3122}," void",[3055,3372,3373],{"class":3168}," Add",[3055,3375,3172],{"class":3069},[3055,3377,3378],{"class":3065},"T",[3055,3380,3381],{"class":3126}," item",[3055,3383,3384],{"class":3069},")\n",[3055,3386,3387],{"class":3057,"line":3093},[3055,3388,3195],{"class":3069},[3055,3390,3391,3394,3396,3399,3402,3405,3407,3410,3413],{"class":3057,"line":3112},[3055,3392,3393],{"class":3061},"    if",[3055,3395,3204],{"class":3069},[3055,3397,3398],{"class":3126},"_size",[3055,3400,3401],{"class":3069}," == ",[3055,3403,3404],{"class":3126},"_items",[3055,3406,3080],{"class":3069},[3055,3408,3409],{"class":3126},"Length",[3055,3411,3412],{"class":3069},")  ",[3055,3414,3415],{"class":3156},"// 1. Перевірка чи потрібно розширити масив\n",[3055,3417,3418],{"class":3057,"line":3119},[3055,3419,3238],{"class":3069},[3055,3421,3422,3425,3427,3429,3431,3434,3436],{"class":3057,"line":3148},[3055,3423,3424],{"class":3168},"        EnsureCapacity",[3055,3426,3172],{"class":3069},[3055,3428,3398],{"class":3126},[3055,3430,3261],{"class":3069},[3055,3432,3433],{"class":3175},"1",[3055,3435,3266],{"class":3069},[3055,3437,3438],{"class":3156},"// 2. Розширення (створення нового масиву)\n",[3055,3440,3441],{"class":3057,"line":3153},[3055,3442,3275],{"class":3069},[3055,3444,3445],{"class":3057,"line":3160},[3055,3446,3116],{"emptyLinePlaceholder":3115},[3055,3448,3449,3452,3455,3457,3460,3463,3466],{"class":3057,"line":3192},[3055,3450,3451],{"class":3126},"    _items",[3055,3453,3454],{"class":3069},"[",[3055,3456,3398],{"class":3126},[3055,3458,3459],{"class":3069},"] = ",[3055,3461,3462],{"class":3126},"item",[3055,3464,3465],{"class":3069},";  ",[3055,3467,3468],{"class":3156},"// 3. Запис елемента\n",[3055,3470,3471,3474,3477],{"class":3057,"line":3198},[3055,3472,3473],{"class":3126},"    _size",[3055,3475,3476],{"class":3069},"++;               ",[3055,3478,3479],{"class":3156},"// 4. Інкремент розміру\n",[3055,3481,3482],{"class":3057,"line":3235},[3055,3483,3484],{"class":3069},"}\n",[2964,3486,3487,3490],{},[2977,3488,3489],{},"Race condition сценарій",":",[3044,3492,3497],{"className":3493,"code":3495,"language":3496},[3494],"language-text","Thread 1                          Thread 2\n────────────────────────────────────────────────────────\nRead _size = 100\n                                  Read _size = 100\nWrite _items[100] = \"A\"\n                                  Write _items[100] = \"B\"  ← Перезаписує \"A\"!\n_size = 101\n                                  _size = 101  ← Той самий індекс!\n","text",[2968,3498,3495],{"__ignoreMap":3051},[2964,3500,3501,3504,3505,3507],{},[2977,3502,3503],{},"Результат",": Елемент \"A\" втрачено, ",[2968,3506,3398],{}," некоректний, можлива corruption внутрішнього масиву.",[3032,3509,3511],{"id":3510},"демонстрація-dictionarykv-exception","Демонстрація: Dictionary\u003CK,V> Exception",[3044,3513,3516],{"className":3046,"code":3514,"filename":3515,"language":3049,"meta":3050,"style":3051},"using System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\n\nvar dict = new Dictionary\u003Cstring, int>();\n\ntry\n{\n    // 10 потоків одночасно додають елементи\n    Parallel.For(0, 10, i =>\n    {\n        for (int j = 0; j \u003C 1000; j++)\n        {\n            string key = $\"key-{i}-{j}\";\n            dict[key] = i * 1000 + j;  // ← НЕ thread-safe!\n        }\n    });\n}\ncatch (Exception ex)\n{\n    Console.WriteLine($\"Exception: {ex.GetType().Name}\");\n    Console.WriteLine($\"Message: {ex.Message}\");\n}\n\n// Типовий результат:\n// Exception: InvalidOperationException\n// Message: Collection was modified; enumeration operation may not execute.\n// АБО: IndexOutOfRangeException, NullReferenceException\n","DictionaryException.cs",[2968,3517,3518,3526,3542,3558,3562,3587,3591,3596,3600,3605,3628,3632,3661,3666,3698,3724,3729,3734,3738,3753,3758,3795,3824,3829,3834,3840,3846,3852],{"__ignoreMap":3051},[3055,3519,3520,3522,3524],{"class":3057,"line":3058},[3055,3521,3062],{"class":3061},[3055,3523,3066],{"class":3065},[3055,3525,3070],{"class":3069},[3055,3527,3528,3530,3532,3534,3536,3538,3540],{"class":3057,"line":3073},[3055,3529,3062],{"class":3061},[3055,3531,3066],{"class":3065},[3055,3533,3080],{"class":3069},[3055,3535,3083],{"class":3065},[3055,3537,3080],{"class":3069},[3055,3539,3088],{"class":3065},[3055,3541,3070],{"class":3069},[3055,3543,3544,3546,3548,3550,3552,3554,3556],{"class":3057,"line":3093},[3055,3545,3062],{"class":3061},[3055,3547,3066],{"class":3065},[3055,3549,3080],{"class":3069},[3055,3551,3102],{"class":3065},[3055,3553,3080],{"class":3069},[3055,3555,3107],{"class":3065},[3055,3557,3070],{"class":3069},[3055,3559,3560],{"class":3057,"line":3112},[3055,3561,3116],{"emptyLinePlaceholder":3115},[3055,3563,3564,3566,3569,3571,3573,3576,3578,3581,3583,3585],{"class":3057,"line":3119},[3055,3565,3123],{"class":3122},[3055,3567,3568],{"class":3126}," dict",[3055,3570,3130],{"class":3069},[3055,3572,3133],{"class":3122},[3055,3574,3575],{"class":3065}," Dictionary",[3055,3577,3139],{"class":3069},[3055,3579,3580],{"class":3122},"string",[3055,3582,2971],{"class":3069},[3055,3584,3142],{"class":3122},[3055,3586,3145],{"class":3069},[3055,3588,3589],{"class":3057,"line":3148},[3055,3590,3116],{"emptyLinePlaceholder":3115},[3055,3592,3593],{"class":3057,"line":3153},[3055,3594,3595],{"class":3061},"try\n",[3055,3597,3598],{"class":3057,"line":3160},[3055,3599,3195],{"class":3069},[3055,3601,3602],{"class":3057,"line":3192},[3055,3603,3604],{"class":3156},"    // 10 потоків одночасно додають елементи\n",[3055,3606,3607,3610,3612,3614,3616,3618,3620,3622,3624,3626],{"class":3057,"line":3198},[3055,3608,3609],{"class":3126},"    Parallel",[3055,3611,3080],{"class":3069},[3055,3613,3169],{"class":3168},[3055,3615,3172],{"class":3069},[3055,3617,3176],{"class":3175},[3055,3619,2971],{"class":3069},[3055,3621,3181],{"class":3175},[3055,3623,2971],{"class":3069},[3055,3625,3186],{"class":3126},[3055,3627,3189],{"class":3069},[3055,3629,3630],{"class":3057,"line":3235},[3055,3631,3238],{"class":3069},[3055,3633,3634,3637,3639,3641,3643,3645,3647,3649,3651,3653,3655,3657,3659],{"class":3057,"line":3241},[3055,3635,3636],{"class":3061},"        for",[3055,3638,3204],{"class":3069},[3055,3640,3142],{"class":3122},[3055,3642,3209],{"class":3126},[3055,3644,3130],{"class":3069},[3055,3646,3176],{"class":3175},[3055,3648,3216],{"class":3069},[3055,3650,3219],{"class":3126},[3055,3652,3222],{"class":3069},[3055,3654,3225],{"class":3175},[3055,3656,3216],{"class":3069},[3055,3658,3219],{"class":3126},[3055,3660,3232],{"class":3069},[3055,3662,3663],{"class":3057,"line":3272},[3055,3664,3665],{"class":3069},"        {\n",[3055,3667,3668,3671,3674,3676,3679,3681,3683,3685,3688,3690,3692,3694,3696],{"class":3057,"line":3278},[3055,3669,3670],{"class":3122},"            string",[3055,3672,3673],{"class":3126}," key",[3055,3675,3130],{"class":3069},[3055,3677,3678],{"class":3302},"$\"key-",[3055,3680,3307],{"class":3306},[3055,3682,3186],{"class":3126},[3055,3684,3318],{"class":3306},[3055,3686,3687],{"class":3302},"-",[3055,3689,3307],{"class":3306},[3055,3691,3219],{"class":3126},[3055,3693,3318],{"class":3306},[3055,3695,3321],{"class":3302},[3055,3697,3070],{"class":3069},[3055,3699,3700,3703,3705,3708,3710,3712,3714,3716,3718,3720,3722],{"class":3057,"line":3284},[3055,3701,3702],{"class":3126},"            dict",[3055,3704,3454],{"class":3069},[3055,3706,3707],{"class":3126},"key",[3055,3709,3459],{"class":3069},[3055,3711,3186],{"class":3126},[3055,3713,3256],{"class":3069},[3055,3715,3225],{"class":3175},[3055,3717,3261],{"class":3069},[3055,3719,3219],{"class":3126},[3055,3721,3465],{"class":3069},[3055,3723,3269],{"class":3156},[3055,3725,3726],{"class":3057,"line":3289},[3055,3727,3728],{"class":3069},"        }\n",[3055,3730,3731],{"class":3057,"line":3327},[3055,3732,3733],{"class":3069},"    });\n",[3055,3735,3736],{"class":3057,"line":3333},[3055,3737,3484],{"class":3069},[3055,3739,3740,3743,3745,3748,3751],{"class":3057,"line":3338},[3055,3741,3742],{"class":3061},"catch",[3055,3744,3204],{"class":3069},[3055,3746,3747],{"class":3065},"Exception",[3055,3749,3750],{"class":3126}," ex",[3055,3752,3384],{"class":3069},[3055,3754,3756],{"class":3057,"line":3755},20,[3055,3757,3195],{"class":3069},[3055,3759,3761,3764,3766,3768,3770,3773,3775,3778,3780,3783,3786,3789,3791,3793],{"class":3057,"line":3760},21,[3055,3762,3763],{"class":3126},"    Console",[3055,3765,3080],{"class":3069},[3055,3767,3297],{"class":3168},[3055,3769,3172],{"class":3069},[3055,3771,3772],{"class":3302},"$\"Exception: ",[3055,3774,3307],{"class":3306},[3055,3776,3777],{"class":3126},"ex",[3055,3779,3080],{"class":3306},[3055,3781,3782],{"class":3168},"GetType",[3055,3784,3785],{"class":3306},"().",[3055,3787,3788],{"class":3126},"Name",[3055,3790,3318],{"class":3306},[3055,3792,3321],{"class":3302},[3055,3794,3324],{"class":3069},[3055,3796,3798,3800,3802,3804,3806,3809,3811,3813,3815,3818,3820,3822],{"class":3057,"line":3797},22,[3055,3799,3763],{"class":3126},[3055,3801,3080],{"class":3069},[3055,3803,3297],{"class":3168},[3055,3805,3172],{"class":3069},[3055,3807,3808],{"class":3302},"$\"Message: ",[3055,3810,3307],{"class":3306},[3055,3812,3777],{"class":3126},[3055,3814,3080],{"class":3306},[3055,3816,3817],{"class":3126},"Message",[3055,3819,3318],{"class":3306},[3055,3821,3321],{"class":3302},[3055,3823,3324],{"class":3069},[3055,3825,3827],{"class":3057,"line":3826},23,[3055,3828,3484],{"class":3069},[3055,3830,3832],{"class":3057,"line":3831},24,[3055,3833,3116],{"emptyLinePlaceholder":3115},[3055,3835,3837],{"class":3057,"line":3836},25,[3055,3838,3839],{"class":3156},"// Типовий результат:\n",[3055,3841,3843],{"class":3057,"line":3842},26,[3055,3844,3845],{"class":3156},"// Exception: InvalidOperationException\n",[3055,3847,3849],{"class":3057,"line":3848},27,[3055,3850,3851],{"class":3156},"// Message: Collection was modified; enumeration operation may not execute.\n",[3055,3853,3855],{"class":3057,"line":3854},28,[3055,3856,3857],{"class":3156},"// АБО: IndexOutOfRangeException, NullReferenceException\n",[2964,3859,3860],{},[2977,3861,3862],{},"Чому Dictionary ще небезпечніший?",[2964,3864,3865,3867,3868,3871,3872,3875],{},[2968,3866,2986],{}," використовує ",[2977,3869,3870],{},"hash table"," з ",[2977,3873,3874],{},"buckets"," (корзинами). При додаванні елемента:",[3877,3878,3879,3882,3885,3888],"ol",{},[3012,3880,3881],{},"Обчислюється hash code ключа",[3012,3883,3884],{},"Визначається bucket (індекс у масиві)",[3012,3886,3887],{},"Елемент додається у linked list всередині bucket",[3012,3889,3890,3891,3894],{},"При досягненні load factor (0.75) — ",[2977,3892,3893],{},"rehashing"," (створення нового масиву, переміщення всіх елементів)",[2964,3896,3897,3900],{},[2977,3898,3899],{},"Rehashing у багатопотоковому коді"," = катастрофа:",[3009,3902,3903,3906,3909],{},[3012,3904,3905],{},"Thread 1 починає rehashing → створює новий масив",[3012,3907,3908],{},"Thread 2 намагається читати зі старого масиву → може отримати null reference",[3012,3910,3911],{},"Thread 3 додає елемент у старий масив → елемент втрачено після rehashing",[3032,3913,3915],{"id":3914},"візуалізація-dictionary-corruption","Візуалізація Dictionary Corruption",[3917,3918,3919],"mermaid",{},[3044,3920,3923],{"className":3921,"code":3922,"language":3917,"meta":3051,"style":3051},"language-mermaid shiki shiki-themes light-plus dark-plus dark-plus","sequenceDiagram\n    participant T1 as Thread 1\n    participant T2 as Thread 2\n    participant D as Dictionary\u003Cbr/>(internal state)\n\n    Note over D: Count = 11, Capacity = 16\u003Cbr/>Load factor = 0.69\n\n    T1->>D: Add(\"key1\", 1)\n    Note over D: Count = 12, Load = 0.75\u003Cbr/>Trigger REHASH!\n\n    T1->>D: Start rehashing...\u003Cbr/>Create new array[32]\n\n    T2->>D: Add(\"key2\", 2)\n    Note over T2: Writes to OLD array!\n\n    T1->>D: Copy elements to new array\n    Note over D: \"key2\" NOT copied!\u003Cbr/>LOST!\n\n    T1->>D: Replace old array with new\n\n    Note over D: Corruption:\u003Cbr/>- \"key2\" lost\u003Cbr/>- Count incorrect\u003Cbr/>- Possible null refs\n",[2968,3924,3925,3930,3935,3940,3945,3949,3954,3958,3963,3968,3972,3977,3981,3986,3991,3995,4000,4005,4009,4014,4018],{"__ignoreMap":3051},[3055,3926,3927],{"class":3057,"line":3058},[3055,3928,3929],{},"sequenceDiagram\n",[3055,3931,3932],{"class":3057,"line":3073},[3055,3933,3934],{},"    participant T1 as Thread 1\n",[3055,3936,3937],{"class":3057,"line":3093},[3055,3938,3939],{},"    participant T2 as Thread 2\n",[3055,3941,3942],{"class":3057,"line":3112},[3055,3943,3944],{},"    participant D as Dictionary\u003Cbr/>(internal state)\n",[3055,3946,3947],{"class":3057,"line":3119},[3055,3948,3116],{"emptyLinePlaceholder":3115},[3055,3950,3951],{"class":3057,"line":3148},[3055,3952,3953],{},"    Note over D: Count = 11, Capacity = 16\u003Cbr/>Load factor = 0.69\n",[3055,3955,3956],{"class":3057,"line":3153},[3055,3957,3116],{"emptyLinePlaceholder":3115},[3055,3959,3960],{"class":3057,"line":3160},[3055,3961,3962],{},"    T1->>D: Add(\"key1\", 1)\n",[3055,3964,3965],{"class":3057,"line":3192},[3055,3966,3967],{},"    Note over D: Count = 12, Load = 0.75\u003Cbr/>Trigger REHASH!\n",[3055,3969,3970],{"class":3057,"line":3198},[3055,3971,3116],{"emptyLinePlaceholder":3115},[3055,3973,3974],{"class":3057,"line":3235},[3055,3975,3976],{},"    T1->>D: Start rehashing...\u003Cbr/>Create new array[32]\n",[3055,3978,3979],{"class":3057,"line":3241},[3055,3980,3116],{"emptyLinePlaceholder":3115},[3055,3982,3983],{"class":3057,"line":3272},[3055,3984,3985],{},"    T2->>D: Add(\"key2\", 2)\n",[3055,3987,3988],{"class":3057,"line":3278},[3055,3989,3990],{},"    Note over T2: Writes to OLD array!\n",[3055,3992,3993],{"class":3057,"line":3284},[3055,3994,3116],{"emptyLinePlaceholder":3115},[3055,3996,3997],{"class":3057,"line":3289},[3055,3998,3999],{},"    T1->>D: Copy elements to new array\n",[3055,4001,4002],{"class":3057,"line":3327},[3055,4003,4004],{},"    Note over D: \"key2\" NOT copied!\u003Cbr/>LOST!\n",[3055,4006,4007],{"class":3057,"line":3333},[3055,4008,3116],{"emptyLinePlaceholder":3115},[3055,4010,4011],{"class":3057,"line":3338},[3055,4012,4013],{},"    T1->>D: Replace old array with new\n",[3055,4015,4016],{"class":3057,"line":3755},[3055,4017,3116],{"emptyLinePlaceholder":3115},[3055,4019,4020],{"class":3057,"line":3760},[3055,4021,4022],{},"    Note over D: Corruption:\u003Cbr/>- \"key2\" lost\u003Cbr/>- Count incorrect\u003Cbr/>- Possible null refs\n",[3032,4024,4026],{"id":4025},"наївне-рішення-lock-навколо-колекції","Наївне Рішення: Lock Навколо Колекції",[3044,4028,4031],{"className":3046,"code":4029,"filename":4030,"language":3049,"meta":3050,"style":3051},"var dict = new Dictionary\u003Cstring, int>();\nvar lockObj = new object();\n\n// ✅ Thread-safe, але ПОВІЛЬНО\nParallel.For(0, 10, i =>\n{\n    for (int j = 0; j \u003C 1000; j++)\n    {\n        string key = $\"key-{i}-{j}\";\n\n        lock (lockObj)  // ← Всі потоки конкурують за ОДИН lock\n        {\n            dict[key] = i * 1000 + j;\n        }\n    }\n});\n\n// Проблеми:\n// 1. Lock contention — всі 10 потоків чекають на один lock\n// 2. Serialization — фактично виконується послідовно\n// 3. Погана scalability — чим більше потоків, тим гірше\n","NaiveLocking.cs",[2968,4032,4033,4055,4072,4076,4081,4103,4107,4135,4139,4168,4172,4187,4191,4213,4217,4221,4225,4229,4234,4239,4244],{"__ignoreMap":3051},[3055,4034,4035,4037,4039,4041,4043,4045,4047,4049,4051,4053],{"class":3057,"line":3058},[3055,4036,3123],{"class":3122},[3055,4038,3568],{"class":3126},[3055,4040,3130],{"class":3069},[3055,4042,3133],{"class":3122},[3055,4044,3575],{"class":3065},[3055,4046,3139],{"class":3069},[3055,4048,3580],{"class":3122},[3055,4050,2971],{"class":3069},[3055,4052,3142],{"class":3122},[3055,4054,3145],{"class":3069},[3055,4056,4057,4059,4062,4064,4066,4069],{"class":3057,"line":3073},[3055,4058,3123],{"class":3122},[3055,4060,4061],{"class":3126}," lockObj",[3055,4063,3130],{"class":3069},[3055,4065,3133],{"class":3122},[3055,4067,4068],{"class":3122}," object",[3055,4070,4071],{"class":3069},"();\n",[3055,4073,4074],{"class":3057,"line":3093},[3055,4075,3116],{"emptyLinePlaceholder":3115},[3055,4077,4078],{"class":3057,"line":3112},[3055,4079,4080],{"class":3156},"// ✅ Thread-safe, але ПОВІЛЬНО\n",[3055,4082,4083,4085,4087,4089,4091,4093,4095,4097,4099,4101],{"class":3057,"line":3119},[3055,4084,3163],{"class":3126},[3055,4086,3080],{"class":3069},[3055,4088,3169],{"class":3168},[3055,4090,3172],{"class":3069},[3055,4092,3176],{"class":3175},[3055,4094,2971],{"class":3069},[3055,4096,3181],{"class":3175},[3055,4098,2971],{"class":3069},[3055,4100,3186],{"class":3126},[3055,4102,3189],{"class":3069},[3055,4104,4105],{"class":3057,"line":3148},[3055,4106,3195],{"class":3069},[3055,4108,4109,4111,4113,4115,4117,4119,4121,4123,4125,4127,4129,4131,4133],{"class":3057,"line":3153},[3055,4110,3201],{"class":3061},[3055,4112,3204],{"class":3069},[3055,4114,3142],{"class":3122},[3055,4116,3209],{"class":3126},[3055,4118,3130],{"class":3069},[3055,4120,3176],{"class":3175},[3055,4122,3216],{"class":3069},[3055,4124,3219],{"class":3126},[3055,4126,3222],{"class":3069},[3055,4128,3225],{"class":3175},[3055,4130,3216],{"class":3069},[3055,4132,3219],{"class":3126},[3055,4134,3232],{"class":3069},[3055,4136,4137],{"class":3057,"line":3160},[3055,4138,3238],{"class":3069},[3055,4140,4141,4144,4146,4148,4150,4152,4154,4156,4158,4160,4162,4164,4166],{"class":3057,"line":3192},[3055,4142,4143],{"class":3122},"        string",[3055,4145,3673],{"class":3126},[3055,4147,3130],{"class":3069},[3055,4149,3678],{"class":3302},[3055,4151,3307],{"class":3306},[3055,4153,3186],{"class":3126},[3055,4155,3318],{"class":3306},[3055,4157,3687],{"class":3302},[3055,4159,3307],{"class":3306},[3055,4161,3219],{"class":3126},[3055,4163,3318],{"class":3306},[3055,4165,3321],{"class":3302},[3055,4167,3070],{"class":3069},[3055,4169,4170],{"class":3057,"line":3198},[3055,4171,3116],{"emptyLinePlaceholder":3115},[3055,4173,4174,4177,4179,4182,4184],{"class":3057,"line":3235},[3055,4175,4176],{"class":3061},"        lock",[3055,4178,3204],{"class":3069},[3055,4180,4181],{"class":3126},"lockObj",[3055,4183,3412],{"class":3069},[3055,4185,4186],{"class":3156},"// ← Всі потоки конкурують за ОДИН lock\n",[3055,4188,4189],{"class":3057,"line":3241},[3055,4190,3665],{"class":3069},[3055,4192,4193,4195,4197,4199,4201,4203,4205,4207,4209,4211],{"class":3057,"line":3272},[3055,4194,3702],{"class":3126},[3055,4196,3454],{"class":3069},[3055,4198,3707],{"class":3126},[3055,4200,3459],{"class":3069},[3055,4202,3186],{"class":3126},[3055,4204,3256],{"class":3069},[3055,4206,3225],{"class":3175},[3055,4208,3261],{"class":3069},[3055,4210,3219],{"class":3126},[3055,4212,3070],{"class":3069},[3055,4214,4215],{"class":3057,"line":3278},[3055,4216,3728],{"class":3069},[3055,4218,4219],{"class":3057,"line":3284},[3055,4220,3275],{"class":3069},[3055,4222,4223],{"class":3057,"line":3289},[3055,4224,3281],{"class":3069},[3055,4226,4227],{"class":3057,"line":3327},[3055,4228,3116],{"emptyLinePlaceholder":3115},[3055,4230,4231],{"class":3057,"line":3333},[3055,4232,4233],{"class":3156},"// Проблеми:\n",[3055,4235,4236],{"class":3057,"line":3338},[3055,4237,4238],{"class":3156},"// 1. Lock contention — всі 10 потоків чекають на один lock\n",[3055,4240,4241],{"class":3057,"line":3755},[3055,4242,4243],{"class":3156},"// 2. Serialization — фактично виконується послідовно\n",[3055,4245,4246],{"class":3057,"line":3760},[3055,4247,4248],{"class":3156},"// 3. Погана scalability — чим більше потоків, тим гірше\n",[2964,4250,4251,3490],{},[2977,4252,4253],{},"Benchmark: Dictionary + lock vs ConcurrentDictionary",[3044,4255,4258],{"className":4256,"code":4257,"language":3496},[3494],"10 потоків × 10,000 операцій кожен:\nDictionary + lock:        ~800ms\nConcurrentDictionary:     ~150ms  (в 5x швидше!)\n",[2968,4259,4257],{"__ignoreMap":3051},[3025,4261],{},[2959,4263,4265],{"id":4264},"concurrentdictionarytkey-tvalue","ConcurrentDictionary\u003CTKey, TValue>",[3032,4267,4269],{"id":4268},"архітектура-striped-locking","Архітектура: Striped Locking",[2964,4271,4272,3867,4275,4278,4279,4282],{},[2968,4273,4274],{},"ConcurrentDictionary",[2977,4276,4277],{},"striped locking"," (смугасте блокування) — замість одного lock на всю колекцію, є ",[2977,4280,4281],{},"кілька locks"," для різних частин:",[3044,4284,4287],{"className":4285,"code":4286,"language":3496},[3494],"┌─────────────────────────────────────────────────────┐\n│         ConcurrentDictionary\u003CK, V>                  │\n├─────────────────────────────────────────────────────┤\n│  Bucket 0-15   │ Lock 0  │  [entries...]           │\n│  Bucket 16-31  │ Lock 1  │  [entries...]           │\n│  Bucket 32-47  │ Lock 2  │  [entries...]           │\n│  Bucket 48-63  │ Lock 3  │  [entries...]           │\n│  ...           │ ...     │  ...                    │\n└─────────────────────────────────────────────────────┘\n\nThread 1 працює з Bucket 5  (Lock 0) ─┐\nThread 2 працює з Bucket 20 (Lock 1) ─┼─ Паралельно!\nThread 3 працює з Bucket 35 (Lock 2) ─┘\n",[2968,4288,4286],{"__ignoreMap":3051},[2964,4290,4291,3490],{},[2977,4292,4293],{},"Переваги",[3009,4295,4296,4303,4306],{},[3012,4297,4298,4299,4302],{},"Кілька потоків можуть працювати ",[2977,4300,4301],{},"одночасно"," якщо вони звертаються до різних buckets",[3012,4304,4305],{},"Lock contention зменшується пропорційно кількості locks",[3012,4307,4308],{},"За замовчуванням: кількість locks = кількість CPU cores × 4",[2964,4310,4311,3490],{},[2977,4312,4313],{},"Trade-off",[3009,4315,4316,4319,4322],{},[3012,4317,4318],{},"Більше пам'яті (кожен lock = об'єкт)",[3012,4320,4321],{},"Складніша реалізація",[3012,4323,4324,4325,4327],{},"Деякі операції (наприклад, ",[2968,4326,3315],{},") потребують захоплення всіх locks",[3032,4329,4331],{"id":4330},"як-працює-striped-locking-детальний-розбір","Як Працює Striped Locking: Детальний Розбір",[2964,4333,4334,4335,4337],{},"Давайте розберемо як саме ",[2968,4336,4274],{}," досягає високої продуктивності через striped locking.",[2964,4339,4340],{},[2977,4341,4342],{},"Крок 1: Визначення bucket",[2964,4344,4345,4346,4349],{},"Коли ви додаєте елемент з ключем, спочатку обчислюється ",[2977,4347,4348],{},"hash code"," ключа:",[3044,4351,4353],{"className":3046,"code":4352,"language":3049,"meta":3051,"style":3051},"int hashCode = key.GetHashCode();\n",[2968,4354,4355],{"__ignoreMap":3051},[3055,4356,4357,4359,4362,4364,4366,4368,4371],{"class":3057,"line":3058},[3055,4358,3142],{"class":3122},[3055,4360,4361],{"class":3126}," hashCode",[3055,4363,3130],{"class":3069},[3055,4365,3707],{"class":3126},[3055,4367,3080],{"class":3069},[3055,4369,4370],{"class":3168},"GetHashCode",[3055,4372,4071],{"class":3069},[2964,4374,4375,4376,4379],{},"Потім hash code використовується для визначення ",[2977,4377,4378],{},"bucket"," (корзини) куди потрапить елемент:",[3044,4381,4383],{"className":3046,"code":4382,"language":3049,"meta":3051,"style":3051},"int bucketIndex = hashCode % totalBuckets;\n",[2968,4384,4385],{"__ignoreMap":3051},[3055,4386,4387,4389,4392,4394,4397,4400,4403],{"class":3057,"line":3058},[3055,4388,3142],{"class":3122},[3055,4390,4391],{"class":3126}," bucketIndex",[3055,4393,3130],{"class":3069},[3055,4395,4396],{"class":3126},"hashCode",[3055,4398,4399],{"class":3069}," % ",[3055,4401,4402],{"class":3126},"totalBuckets",[3055,4404,3070],{"class":3069},[2964,4406,4407],{},[2977,4408,4409],{},"Крок 2: Визначення lock",[2964,4411,4412,4413,4416],{},"Кожен bucket належить до певного ",[2977,4414,4415],{},"lock segment",". Наприклад, якщо є 64 buckets та 4 locks:",[3044,4418,4421],{"className":4419,"code":4420,"language":3496},[3494],"Buckets 0-15   → Lock 0\nBuckets 16-31  → Lock 1\nBuckets 32-47  → Lock 2\nBuckets 48-63  → Lock 3\n",[2968,4422,4420],{"__ignoreMap":3051},[2964,4424,4425],{},[2977,4426,4427],{},"Крок 3: Захоплення lock та модифікація",[2964,4429,4430,4431,4434,4435,3080],{},"Тільки потоки що працюють з ",[2977,4432,4433],{},"тим самим lock segment"," конкурують між собою. Потоки що працюють з різними segments — працюють ",[2977,4436,4437],{},"паралельно",[2964,4439,4440,3490],{},[2977,4441,4442],{},"Приклад сценарію",[3044,4444,4447],{"className":4445,"code":4446,"language":3496},[3494],"Thread 1: Add(\"apple\", 10)\n  → hashCode = 12345\n  → bucket = 12345 % 64 = 5\n  → Lock 0 (buckets 0-15)\n  → Захоплює Lock 0, додає елемент\n\nThread 2: Add(\"banana\", 20)\n  → hashCode = 67890\n  → bucket = 67890 % 64 = 26\n  → Lock 1 (buckets 16-31)\n  → Захоплює Lock 1, додає елемент ПАРАЛЕЛЬНО з Thread 1!\n\nThread 3: Add(\"avocado\", 30)\n  → hashCode = 11111\n  → bucket = 11111 % 64 = 7\n  → Lock 0 (buckets 0-15)\n  → ЧЕКАЄ поки Thread 1 звільнить Lock 0\n",[2968,4448,4446],{"__ignoreMap":3051},[2964,4450,4451],{},[2977,4452,4453],{},"Чому це швидше ніж один lock?",[2964,4455,4456,4457,4460],{},"З одним lock на всю колекцію, Thread 2 мав би чекати Thread 1, навіть якщо вони працюють з ",[2977,4458,4459],{},"різними"," частинами колекції. Striped locking дозволяє їм працювати паралельно, що значно підвищує throughput на багатоядерних системах.",[2964,4462,4463,3490],{},[2977,4464,4465],{},"Візуалізація через Mermaid",[3917,4467,4468],{},[3044,4469,4471],{"className":3921,"code":4470,"language":3917,"meta":3051,"style":3051},"sequenceDiagram\n    participant T1 as Thread 1\n    participant L0 as Lock 0\n    participant T2 as Thread 2\n    participant L1 as Lock 1\n    participant T3 as Thread 3\n\n    Note over T1,T3: Три потоки одночасно додають елементи\n\n    T1->>L0: Add(\"apple\") → bucket 5\n    activate L0\n    Note over L0: Lock 0 захоплено\n\n    T2->>L1: Add(\"banana\") → bucket 26\n    activate L1\n    Note over L1: Lock 1 захоплено\u003Cbr/>ПАРАЛЕЛЬНО з Lock 0!\n\n    T3->>L0: Add(\"avocado\") → bucket 7\n    Note over T3: Чекає Lock 0...\n\n    T1->>L0: Додано \"apple\"\n    deactivate L0\n\n    L0->>T3: Lock 0 звільнено\n    activate L0\n    T3->>L0: Додано \"avocado\"\n    deactivate L0\n\n    T2->>L1: Додано \"banana\"\n    deactivate L1\n",[2968,4472,4473,4477,4481,4486,4490,4495,4500,4504,4509,4513,4518,4523,4528,4532,4537,4542,4547,4551,4556,4561,4565,4570,4575,4579,4584,4588,4593,4597,4601,4607],{"__ignoreMap":3051},[3055,4474,4475],{"class":3057,"line":3058},[3055,4476,3929],{},[3055,4478,4479],{"class":3057,"line":3073},[3055,4480,3934],{},[3055,4482,4483],{"class":3057,"line":3093},[3055,4484,4485],{},"    participant L0 as Lock 0\n",[3055,4487,4488],{"class":3057,"line":3112},[3055,4489,3939],{},[3055,4491,4492],{"class":3057,"line":3119},[3055,4493,4494],{},"    participant L1 as Lock 1\n",[3055,4496,4497],{"class":3057,"line":3148},[3055,4498,4499],{},"    participant T3 as Thread 3\n",[3055,4501,4502],{"class":3057,"line":3153},[3055,4503,3116],{"emptyLinePlaceholder":3115},[3055,4505,4506],{"class":3057,"line":3160},[3055,4507,4508],{},"    Note over T1,T3: Три потоки одночасно додають елементи\n",[3055,4510,4511],{"class":3057,"line":3192},[3055,4512,3116],{"emptyLinePlaceholder":3115},[3055,4514,4515],{"class":3057,"line":3198},[3055,4516,4517],{},"    T1->>L0: Add(\"apple\") → bucket 5\n",[3055,4519,4520],{"class":3057,"line":3235},[3055,4521,4522],{},"    activate L0\n",[3055,4524,4525],{"class":3057,"line":3241},[3055,4526,4527],{},"    Note over L0: Lock 0 захоплено\n",[3055,4529,4530],{"class":3057,"line":3272},[3055,4531,3116],{"emptyLinePlaceholder":3115},[3055,4533,4534],{"class":3057,"line":3278},[3055,4535,4536],{},"    T2->>L1: Add(\"banana\") → bucket 26\n",[3055,4538,4539],{"class":3057,"line":3284},[3055,4540,4541],{},"    activate L1\n",[3055,4543,4544],{"class":3057,"line":3289},[3055,4545,4546],{},"    Note over L1: Lock 1 захоплено\u003Cbr/>ПАРАЛЕЛЬНО з Lock 0!\n",[3055,4548,4549],{"class":3057,"line":3327},[3055,4550,3116],{"emptyLinePlaceholder":3115},[3055,4552,4553],{"class":3057,"line":3333},[3055,4554,4555],{},"    T3->>L0: Add(\"avocado\") → bucket 7\n",[3055,4557,4558],{"class":3057,"line":3338},[3055,4559,4560],{},"    Note over T3: Чекає Lock 0...\n",[3055,4562,4563],{"class":3057,"line":3755},[3055,4564,3116],{"emptyLinePlaceholder":3115},[3055,4566,4567],{"class":3057,"line":3760},[3055,4568,4569],{},"    T1->>L0: Додано \"apple\"\n",[3055,4571,4572],{"class":3057,"line":3797},[3055,4573,4574],{},"    deactivate L0\n",[3055,4576,4577],{"class":3057,"line":3826},[3055,4578,3116],{"emptyLinePlaceholder":3115},[3055,4580,4581],{"class":3057,"line":3831},[3055,4582,4583],{},"    L0->>T3: Lock 0 звільнено\n",[3055,4585,4586],{"class":3057,"line":3836},[3055,4587,4522],{},[3055,4589,4590],{"class":3057,"line":3842},[3055,4591,4592],{},"    T3->>L0: Додано \"avocado\"\n",[3055,4594,4595],{"class":3057,"line":3848},[3055,4596,4574],{},[3055,4598,4599],{"class":3057,"line":3854},[3055,4600,3116],{"emptyLinePlaceholder":3115},[3055,4602,4604],{"class":3057,"line":4603},29,[3055,4605,4606],{},"    T2->>L1: Додано \"banana\"\n",[3055,4608,4610],{"class":3057,"line":4609},30,[3055,4611,4612],{},"    deactivate L1\n",[2964,4614,4615,4618],{},[2977,4616,4617],{},"Ключовий висновок",": Striped locking перетворює \"один вузьке місце\" (single lock) на \"кілька менших вузьких місць\" (multiple locks), що дозволяє більшій кількості потоків працювати одночасно.",[3032,4620,4622],{"id":4621},"основні-методи","Основні Методи",[4624,4625,4627],"h4",{"id":4626},"tryadd-додати-якщо-немає","TryAdd — Додати Якщо Немає",[3044,4629,4632],{"className":3046,"code":4630,"filename":4631,"language":3049,"meta":3050,"style":3051},"var dict = new ConcurrentDictionary\u003Cstring, int>();\n\n// Спроба додати елемент\nbool added = dict.TryAdd(\"key1\", 100);\nConsole.WriteLine($\"Added: {added}\");  // true\n\n// Повторна спроба — не вдасться (ключ вже є)\nadded = dict.TryAdd(\"key1\", 200);\nConsole.WriteLine($\"Added: {added}\");  // false\n\nConsole.WriteLine($\"Value: {dict[\"key1\"]}\");  // 100 (не змінилось)\n","TryAdd.cs",[2968,4633,4634,4657,4661,4666,4696,4723,4727,4732,4755,4780,4784],{"__ignoreMap":3051},[3055,4635,4636,4638,4640,4642,4644,4647,4649,4651,4653,4655],{"class":3057,"line":3058},[3055,4637,3123],{"class":3122},[3055,4639,3568],{"class":3126},[3055,4641,3130],{"class":3069},[3055,4643,3133],{"class":3122},[3055,4645,4646],{"class":3065}," ConcurrentDictionary",[3055,4648,3139],{"class":3069},[3055,4650,3580],{"class":3122},[3055,4652,2971],{"class":3069},[3055,4654,3142],{"class":3122},[3055,4656,3145],{"class":3069},[3055,4658,4659],{"class":3057,"line":3073},[3055,4660,3116],{"emptyLinePlaceholder":3115},[3055,4662,4663],{"class":3057,"line":3093},[3055,4664,4665],{"class":3156},"// Спроба додати елемент\n",[3055,4667,4668,4671,4674,4676,4679,4681,4684,4686,4689,4691,4694],{"class":3057,"line":3112},[3055,4669,4670],{"class":3122},"bool",[3055,4672,4673],{"class":3126}," added",[3055,4675,3130],{"class":3069},[3055,4677,4678],{"class":3126},"dict",[3055,4680,3080],{"class":3069},[3055,4682,4683],{"class":3168},"TryAdd",[3055,4685,3172],{"class":3069},[3055,4687,4688],{"class":3302},"\"key1\"",[3055,4690,2971],{"class":3069},[3055,4692,4693],{"class":3175},"100",[3055,4695,3324],{"class":3069},[3055,4697,4698,4700,4702,4704,4706,4709,4711,4714,4716,4718,4720],{"class":3057,"line":3119},[3055,4699,3292],{"class":3126},[3055,4701,3080],{"class":3069},[3055,4703,3297],{"class":3168},[3055,4705,3172],{"class":3069},[3055,4707,4708],{"class":3302},"$\"Added: ",[3055,4710,3307],{"class":3306},[3055,4712,4713],{"class":3126},"added",[3055,4715,3318],{"class":3306},[3055,4717,3321],{"class":3302},[3055,4719,3266],{"class":3069},[3055,4721,4722],{"class":3156},"// true\n",[3055,4724,4725],{"class":3057,"line":3148},[3055,4726,3116],{"emptyLinePlaceholder":3115},[3055,4728,4729],{"class":3057,"line":3153},[3055,4730,4731],{"class":3156},"// Повторна спроба — не вдасться (ключ вже є)\n",[3055,4733,4734,4736,4738,4740,4742,4744,4746,4748,4750,4753],{"class":3057,"line":3160},[3055,4735,4713],{"class":3126},[3055,4737,3130],{"class":3069},[3055,4739,4678],{"class":3126},[3055,4741,3080],{"class":3069},[3055,4743,4683],{"class":3168},[3055,4745,3172],{"class":3069},[3055,4747,4688],{"class":3302},[3055,4749,2971],{"class":3069},[3055,4751,4752],{"class":3175},"200",[3055,4754,3324],{"class":3069},[3055,4756,4757,4759,4761,4763,4765,4767,4769,4771,4773,4775,4777],{"class":3057,"line":3192},[3055,4758,3292],{"class":3126},[3055,4760,3080],{"class":3069},[3055,4762,3297],{"class":3168},[3055,4764,3172],{"class":3069},[3055,4766,4708],{"class":3302},[3055,4768,3307],{"class":3306},[3055,4770,4713],{"class":3126},[3055,4772,3318],{"class":3306},[3055,4774,3321],{"class":3302},[3055,4776,3266],{"class":3069},[3055,4778,4779],{"class":3156},"// false\n",[3055,4781,4782],{"class":3057,"line":3198},[3055,4783,3116],{"emptyLinePlaceholder":3115},[3055,4785,4786,4788,4790,4792,4794,4797,4799,4801,4803,4805,4808,4810,4812],{"class":3057,"line":3235},[3055,4787,3292],{"class":3126},[3055,4789,3080],{"class":3069},[3055,4791,3297],{"class":3168},[3055,4793,3172],{"class":3069},[3055,4795,4796],{"class":3302},"$\"Value: ",[3055,4798,3307],{"class":3306},[3055,4800,4678],{"class":3126},[3055,4802,3454],{"class":3306},[3055,4804,4688],{"class":3302},[3055,4806,4807],{"class":3306},"]}",[3055,4809,3321],{"class":3302},[3055,4811,3266],{"class":3069},[3055,4813,4814],{"class":3156},"// 100 (не змінилось)\n",[2964,4816,4817,4820,4821,4824],{},[2977,4818,4819],{},"Коли використовувати",": Коли потрібно додати елемент ",[2977,4822,4823],{},"тільки якщо його ще немає",", і ви хочете знати чи операція вдалась.",[4624,4826,4828],{"id":4827},"trygetvalue-безпечне-читання","TryGetValue — Безпечне Читання",[3044,4830,4833],{"className":3046,"code":4831,"filename":4832,"language":3049,"meta":3050,"style":3051},"var dict = new ConcurrentDictionary\u003Cstring, int>();\ndict.TryAdd(\"key1\", 100);\n\n// ✅ Безпечний спосіб читання\nif (dict.TryGetValue(\"key1\", out int value))\n{\n    Console.WriteLine($\"Found: {value}\");\n}\nelse\n{\n    Console.WriteLine(\"Not found\");\n}\n\n// ❌ Небезпечний спосіб (може кинути KeyNotFoundException)\n// int value = dict[\"key1\"];\n","TryGetValue.cs",[2968,4834,4835,4857,4875,4879,4884,4916,4920,4944,4948,4953,4957,4972,4976,4980,4985],{"__ignoreMap":3051},[3055,4836,4837,4839,4841,4843,4845,4847,4849,4851,4853,4855],{"class":3057,"line":3058},[3055,4838,3123],{"class":3122},[3055,4840,3568],{"class":3126},[3055,4842,3130],{"class":3069},[3055,4844,3133],{"class":3122},[3055,4846,4646],{"class":3065},[3055,4848,3139],{"class":3069},[3055,4850,3580],{"class":3122},[3055,4852,2971],{"class":3069},[3055,4854,3142],{"class":3122},[3055,4856,3145],{"class":3069},[3055,4858,4859,4861,4863,4865,4867,4869,4871,4873],{"class":3057,"line":3073},[3055,4860,4678],{"class":3126},[3055,4862,3080],{"class":3069},[3055,4864,4683],{"class":3168},[3055,4866,3172],{"class":3069},[3055,4868,4688],{"class":3302},[3055,4870,2971],{"class":3069},[3055,4872,4693],{"class":3175},[3055,4874,3324],{"class":3069},[3055,4876,4877],{"class":3057,"line":3093},[3055,4878,3116],{"emptyLinePlaceholder":3115},[3055,4880,4881],{"class":3057,"line":3112},[3055,4882,4883],{"class":3156},"// ✅ Безпечний спосіб читання\n",[3055,4885,4886,4889,4891,4893,4895,4898,4900,4902,4904,4907,4910,4913],{"class":3057,"line":3119},[3055,4887,4888],{"class":3061},"if",[3055,4890,3204],{"class":3069},[3055,4892,4678],{"class":3126},[3055,4894,3080],{"class":3069},[3055,4896,4897],{"class":3168},"TryGetValue",[3055,4899,3172],{"class":3069},[3055,4901,4688],{"class":3302},[3055,4903,2971],{"class":3069},[3055,4905,4906],{"class":3122},"out",[3055,4908,4909],{"class":3122}," int",[3055,4911,4912],{"class":3126}," value",[3055,4914,4915],{"class":3069},"))\n",[3055,4917,4918],{"class":3057,"line":3148},[3055,4919,3195],{"class":3069},[3055,4921,4922,4924,4926,4928,4930,4933,4935,4938,4940,4942],{"class":3057,"line":3153},[3055,4923,3763],{"class":3126},[3055,4925,3080],{"class":3069},[3055,4927,3297],{"class":3168},[3055,4929,3172],{"class":3069},[3055,4931,4932],{"class":3302},"$\"Found: ",[3055,4934,3307],{"class":3306},[3055,4936,4937],{"class":3126},"value",[3055,4939,3318],{"class":3306},[3055,4941,3321],{"class":3302},[3055,4943,3324],{"class":3069},[3055,4945,4946],{"class":3057,"line":3160},[3055,4947,3484],{"class":3069},[3055,4949,4950],{"class":3057,"line":3192},[3055,4951,4952],{"class":3061},"else\n",[3055,4954,4955],{"class":3057,"line":3198},[3055,4956,3195],{"class":3069},[3055,4958,4959,4961,4963,4965,4967,4970],{"class":3057,"line":3235},[3055,4960,3763],{"class":3126},[3055,4962,3080],{"class":3069},[3055,4964,3297],{"class":3168},[3055,4966,3172],{"class":3069},[3055,4968,4969],{"class":3302},"\"Not found\"",[3055,4971,3324],{"class":3069},[3055,4973,4974],{"class":3057,"line":3241},[3055,4975,3484],{"class":3069},[3055,4977,4978],{"class":3057,"line":3272},[3055,4979,3116],{"emptyLinePlaceholder":3115},[3055,4981,4982],{"class":3057,"line":3278},[3055,4983,4984],{"class":3156},"// ❌ Небезпечний спосіб (може кинути KeyNotFoundException)\n",[3055,4986,4987],{"class":3057,"line":3284},[3055,4988,4989],{"class":3156},"// int value = dict[\"key1\"];\n",[2964,4991,4992,3490],{},[2977,4993,4994],{},"Чому TryGetValue краще за indexer",[3009,4996,4997,5000,5007],{},[3012,4998,4999],{},"Не кидає exception якщо ключа немає",[3012,5001,5002,5003,5006],{},"Одна операція замість двох (",[2968,5004,5005],{},"ContainsKey"," + indexer)",[3012,5008,5009],{},"Thread-safe гарантія що значення не зміниться між перевіркою та читанням",[4624,5011,5013],{"id":5012},"getoradd-отримати-або-додати","GetOrAdd — Отримати або Додати",[3044,5015,5018],{"className":3046,"code":5016,"filename":5017,"language":3049,"meta":3050,"style":3051},"var dict = new ConcurrentDictionary\u003Cstring, int>();\n\n// Варіант 1: з готовим значенням\nint value1 = dict.GetOrAdd(\"key1\", 100);\nConsole.WriteLine(value1);  // 100 (додано)\n\nint value2 = dict.GetOrAdd(\"key1\", 200);\nConsole.WriteLine(value2);  // 100 (вже було, не змінилось)\n\n// Варіант 2: з factory function (викликається тільки якщо ключа немає)\nint value3 = dict.GetOrAdd(\"key2\", key =>\n{\n    Console.WriteLine($\"Computing value for {key}...\");\n    return ExpensiveComputation();  // Дорога операція\n});\n\n// Варіант 3: з factoryArgument (без closure allocation)\nint value4 = dict.GetOrAdd(\"key3\",\n    static (key, arg) => arg * 2,  // static lambda = no closure\n    factoryArgument: 50);\nConsole.WriteLine(value4);  // 100\n","GetOrAdd.cs",[2968,5019,5020,5042,5046,5051,5077,5095,5099,5124,5142,5146,5151,5177,5181,5205,5219,5223,5227,5232,5255,5285,5298],{"__ignoreMap":3051},[3055,5021,5022,5024,5026,5028,5030,5032,5034,5036,5038,5040],{"class":3057,"line":3058},[3055,5023,3123],{"class":3122},[3055,5025,3568],{"class":3126},[3055,5027,3130],{"class":3069},[3055,5029,3133],{"class":3122},[3055,5031,4646],{"class":3065},[3055,5033,3139],{"class":3069},[3055,5035,3580],{"class":3122},[3055,5037,2971],{"class":3069},[3055,5039,3142],{"class":3122},[3055,5041,3145],{"class":3069},[3055,5043,5044],{"class":3057,"line":3073},[3055,5045,3116],{"emptyLinePlaceholder":3115},[3055,5047,5048],{"class":3057,"line":3093},[3055,5049,5050],{"class":3156},"// Варіант 1: з готовим значенням\n",[3055,5052,5053,5055,5058,5060,5062,5064,5067,5069,5071,5073,5075],{"class":3057,"line":3112},[3055,5054,3142],{"class":3122},[3055,5056,5057],{"class":3126}," value1",[3055,5059,3130],{"class":3069},[3055,5061,4678],{"class":3126},[3055,5063,3080],{"class":3069},[3055,5065,5066],{"class":3168},"GetOrAdd",[3055,5068,3172],{"class":3069},[3055,5070,4688],{"class":3302},[3055,5072,2971],{"class":3069},[3055,5074,4693],{"class":3175},[3055,5076,3324],{"class":3069},[3055,5078,5079,5081,5083,5085,5087,5090,5092],{"class":3057,"line":3119},[3055,5080,3292],{"class":3126},[3055,5082,3080],{"class":3069},[3055,5084,3297],{"class":3168},[3055,5086,3172],{"class":3069},[3055,5088,5089],{"class":3126},"value1",[3055,5091,3266],{"class":3069},[3055,5093,5094],{"class":3156},"// 100 (додано)\n",[3055,5096,5097],{"class":3057,"line":3148},[3055,5098,3116],{"emptyLinePlaceholder":3115},[3055,5100,5101,5103,5106,5108,5110,5112,5114,5116,5118,5120,5122],{"class":3057,"line":3153},[3055,5102,3142],{"class":3122},[3055,5104,5105],{"class":3126}," value2",[3055,5107,3130],{"class":3069},[3055,5109,4678],{"class":3126},[3055,5111,3080],{"class":3069},[3055,5113,5066],{"class":3168},[3055,5115,3172],{"class":3069},[3055,5117,4688],{"class":3302},[3055,5119,2971],{"class":3069},[3055,5121,4752],{"class":3175},[3055,5123,3324],{"class":3069},[3055,5125,5126,5128,5130,5132,5134,5137,5139],{"class":3057,"line":3160},[3055,5127,3292],{"class":3126},[3055,5129,3080],{"class":3069},[3055,5131,3297],{"class":3168},[3055,5133,3172],{"class":3069},[3055,5135,5136],{"class":3126},"value2",[3055,5138,3266],{"class":3069},[3055,5140,5141],{"class":3156},"// 100 (вже було, не змінилось)\n",[3055,5143,5144],{"class":3057,"line":3192},[3055,5145,3116],{"emptyLinePlaceholder":3115},[3055,5147,5148],{"class":3057,"line":3198},[3055,5149,5150],{"class":3156},"// Варіант 2: з factory function (викликається тільки якщо ключа немає)\n",[3055,5152,5153,5155,5158,5160,5162,5164,5166,5168,5171,5173,5175],{"class":3057,"line":3235},[3055,5154,3142],{"class":3122},[3055,5156,5157],{"class":3126}," value3",[3055,5159,3130],{"class":3069},[3055,5161,4678],{"class":3126},[3055,5163,3080],{"class":3069},[3055,5165,5066],{"class":3168},[3055,5167,3172],{"class":3069},[3055,5169,5170],{"class":3302},"\"key2\"",[3055,5172,2971],{"class":3069},[3055,5174,3707],{"class":3126},[3055,5176,3189],{"class":3069},[3055,5178,5179],{"class":3057,"line":3241},[3055,5180,3195],{"class":3069},[3055,5182,5183,5185,5187,5189,5191,5194,5196,5198,5200,5203],{"class":3057,"line":3272},[3055,5184,3763],{"class":3126},[3055,5186,3080],{"class":3069},[3055,5188,3297],{"class":3168},[3055,5190,3172],{"class":3069},[3055,5192,5193],{"class":3302},"$\"Computing value for ",[3055,5195,3307],{"class":3306},[3055,5197,3707],{"class":3126},[3055,5199,3318],{"class":3306},[3055,5201,5202],{"class":3302},"...\"",[3055,5204,3324],{"class":3069},[3055,5206,5207,5210,5213,5216],{"class":3057,"line":3278},[3055,5208,5209],{"class":3061},"    return",[3055,5211,5212],{"class":3168}," ExpensiveComputation",[3055,5214,5215],{"class":3069},"();  ",[3055,5217,5218],{"class":3156},"// Дорога операція\n",[3055,5220,5221],{"class":3057,"line":3284},[3055,5222,3281],{"class":3069},[3055,5224,5225],{"class":3057,"line":3289},[3055,5226,3116],{"emptyLinePlaceholder":3115},[3055,5228,5229],{"class":3057,"line":3327},[3055,5230,5231],{"class":3156},"// Варіант 3: з factoryArgument (без closure allocation)\n",[3055,5233,5234,5236,5239,5241,5243,5245,5247,5249,5252],{"class":3057,"line":3333},[3055,5235,3142],{"class":3122},[3055,5237,5238],{"class":3126}," value4",[3055,5240,3130],{"class":3069},[3055,5242,4678],{"class":3126},[3055,5244,3080],{"class":3069},[3055,5246,5066],{"class":3168},[3055,5248,3172],{"class":3069},[3055,5250,5251],{"class":3302},"\"key3\"",[3055,5253,5254],{"class":3069},",\n",[3055,5256,5257,5260,5262,5264,5266,5269,5272,5274,5276,5279,5282],{"class":3057,"line":3338},[3055,5258,5259],{"class":3122},"    static",[3055,5261,3204],{"class":3069},[3055,5263,3707],{"class":3126},[3055,5265,2971],{"class":3069},[3055,5267,5268],{"class":3126},"arg",[3055,5270,5271],{"class":3069},") => ",[3055,5273,5268],{"class":3126},[3055,5275,3256],{"class":3069},[3055,5277,5278],{"class":3175},"2",[3055,5280,5281],{"class":3069},",  ",[3055,5283,5284],{"class":3156},"// static lambda = no closure\n",[3055,5286,5287,5290,5293,5296],{"class":3057,"line":3755},[3055,5288,5289],{"class":3126},"    factoryArgument",[3055,5291,5292],{"class":3069},": ",[3055,5294,5295],{"class":3175},"50",[3055,5297,3324],{"class":3069},[3055,5299,5300,5302,5304,5306,5308,5311,5313],{"class":3057,"line":3760},[3055,5301,3292],{"class":3126},[3055,5303,3080],{"class":3069},[3055,5305,3297],{"class":3168},[3055,5307,3172],{"class":3069},[3055,5309,5310],{"class":3126},"value4",[3055,5312,3266],{"class":3069},[3055,5314,5315],{"class":3156},"// 100\n",[2964,5317,5318,5321,5322,5325],{},[2977,5319,5320],{},"Важливо",": Factory function може бути викликана ",[2977,5323,5324],{},"кілька разів"," якщо кілька потоків одночасно намагаються додати той самий ключ. Тільки один результат буде збережено, решта відкинуті.",[3044,5327,5329],{"className":3046,"code":5328,"language":3049,"meta":3051,"style":3051},"// ⚠️ Factory може викликатись кілька разів!\nvar dict = new ConcurrentDictionary\u003Cstring, int>();\n\nParallel.For(0, 10, i =>\n{\n    dict.GetOrAdd(\"same-key\", key =>\n    {\n        Console.WriteLine($\"Thread {i} computing...\");\n        return i;\n    });\n});\n\n// Вивід:\n// Thread 0 computing...\n// Thread 1 computing...  ← Обидва обчислюють!\n// Thread 2 computing...\n// ...\n// Але тільки ОДНЕ значення буде збережено\n",[2968,5330,5331,5336,5358,5362,5384,5388,5408,5412,5437,5447,5451,5455,5459,5464,5469,5474,5479,5484],{"__ignoreMap":3051},[3055,5332,5333],{"class":3057,"line":3058},[3055,5334,5335],{"class":3156},"// ⚠️ Factory може викликатись кілька разів!\n",[3055,5337,5338,5340,5342,5344,5346,5348,5350,5352,5354,5356],{"class":3057,"line":3073},[3055,5339,3123],{"class":3122},[3055,5341,3568],{"class":3126},[3055,5343,3130],{"class":3069},[3055,5345,3133],{"class":3122},[3055,5347,4646],{"class":3065},[3055,5349,3139],{"class":3069},[3055,5351,3580],{"class":3122},[3055,5353,2971],{"class":3069},[3055,5355,3142],{"class":3122},[3055,5357,3145],{"class":3069},[3055,5359,5360],{"class":3057,"line":3093},[3055,5361,3116],{"emptyLinePlaceholder":3115},[3055,5363,5364,5366,5368,5370,5372,5374,5376,5378,5380,5382],{"class":3057,"line":3112},[3055,5365,3163],{"class":3126},[3055,5367,3080],{"class":3069},[3055,5369,3169],{"class":3168},[3055,5371,3172],{"class":3069},[3055,5373,3176],{"class":3175},[3055,5375,2971],{"class":3069},[3055,5377,3181],{"class":3175},[3055,5379,2971],{"class":3069},[3055,5381,3186],{"class":3126},[3055,5383,3189],{"class":3069},[3055,5385,5386],{"class":3057,"line":3119},[3055,5387,3195],{"class":3069},[3055,5389,5390,5393,5395,5397,5399,5402,5404,5406],{"class":3057,"line":3148},[3055,5391,5392],{"class":3126},"    dict",[3055,5394,3080],{"class":3069},[3055,5396,5066],{"class":3168},[3055,5398,3172],{"class":3069},[3055,5400,5401],{"class":3302},"\"same-key\"",[3055,5403,2971],{"class":3069},[3055,5405,3707],{"class":3126},[3055,5407,3189],{"class":3069},[3055,5409,5410],{"class":3057,"line":3153},[3055,5411,3238],{"class":3069},[3055,5413,5414,5417,5419,5421,5423,5426,5428,5430,5432,5435],{"class":3057,"line":3160},[3055,5415,5416],{"class":3126},"        Console",[3055,5418,3080],{"class":3069},[3055,5420,3297],{"class":3168},[3055,5422,3172],{"class":3069},[3055,5424,5425],{"class":3302},"$\"Thread ",[3055,5427,3307],{"class":3306},[3055,5429,3186],{"class":3126},[3055,5431,3318],{"class":3306},[3055,5433,5434],{"class":3302}," computing...\"",[3055,5436,3324],{"class":3069},[3055,5438,5439,5442,5445],{"class":3057,"line":3192},[3055,5440,5441],{"class":3061},"        return",[3055,5443,5444],{"class":3126}," i",[3055,5446,3070],{"class":3069},[3055,5448,5449],{"class":3057,"line":3198},[3055,5450,3733],{"class":3069},[3055,5452,5453],{"class":3057,"line":3235},[3055,5454,3281],{"class":3069},[3055,5456,5457],{"class":3057,"line":3241},[3055,5458,3116],{"emptyLinePlaceholder":3115},[3055,5460,5461],{"class":3057,"line":3272},[3055,5462,5463],{"class":3156},"// Вивід:\n",[3055,5465,5466],{"class":3057,"line":3278},[3055,5467,5468],{"class":3156},"// Thread 0 computing...\n",[3055,5470,5471],{"class":3057,"line":3284},[3055,5472,5473],{"class":3156},"// Thread 1 computing...  ← Обидва обчислюють!\n",[3055,5475,5476],{"class":3057,"line":3289},[3055,5477,5478],{"class":3156},"// Thread 2 computing...\n",[3055,5480,5481],{"class":3057,"line":3327},[3055,5482,5483],{"class":3156},"// ...\n",[3055,5485,5486],{"class":3057,"line":3333},[3055,5487,5488],{"class":3156},"// Але тільки ОДНЕ значення буде збережено\n",[4624,5490,5492],{"id":5491},"addorupdate-додати-або-оновити","AddOrUpdate — Додати або Оновити",[3044,5494,5497],{"className":3046,"code":5495,"filename":5496,"language":3049,"meta":3050,"style":3051},"var dict = new ConcurrentDictionary\u003Cstring, int>();\n\n// Варіант 1: з готовими значеннями\nint result1 = dict.AddOrUpdate(\n    key: \"counter\",\n    addValue: 1,                    // Якщо ключа немає → додати 1\n    updateValueFactory: (key, oldValue) => oldValue + 1  // Якщо є → інкремент\n);\nConsole.WriteLine(result1);  // 1 (додано)\n\nint result2 = dict.AddOrUpdate(\"counter\", 1, (key, oldValue) => oldValue + 1);\nConsole.WriteLine(result2);  // 2 (оновлено)\n\n// Варіант 2: з factoryArgument (без closure)\nint result3 = dict.AddOrUpdate(\n    key: \"counter\",\n    addValueFactory: static (key, arg) => arg,\n    updateValueFactory: static (key, oldValue, arg) => oldValue + arg,\n    factoryArgument: 10\n);\nConsole.WriteLine(result3);  // 12 (2 + 10)\n","AddOrUpdate.cs",[2968,5498,5499,5521,5525,5530,5549,5561,5576,5602,5606,5624,5628,5670,5688,5692,5697,5714,5724,5748,5778,5787,5791],{"__ignoreMap":3051},[3055,5500,5501,5503,5505,5507,5509,5511,5513,5515,5517,5519],{"class":3057,"line":3058},[3055,5502,3123],{"class":3122},[3055,5504,3568],{"class":3126},[3055,5506,3130],{"class":3069},[3055,5508,3133],{"class":3122},[3055,5510,4646],{"class":3065},[3055,5512,3139],{"class":3069},[3055,5514,3580],{"class":3122},[3055,5516,2971],{"class":3069},[3055,5518,3142],{"class":3122},[3055,5520,3145],{"class":3069},[3055,5522,5523],{"class":3057,"line":3073},[3055,5524,3116],{"emptyLinePlaceholder":3115},[3055,5526,5527],{"class":3057,"line":3093},[3055,5528,5529],{"class":3156},"// Варіант 1: з готовими значеннями\n",[3055,5531,5532,5534,5537,5539,5541,5543,5546],{"class":3057,"line":3112},[3055,5533,3142],{"class":3122},[3055,5535,5536],{"class":3126}," result1",[3055,5538,3130],{"class":3069},[3055,5540,4678],{"class":3126},[3055,5542,3080],{"class":3069},[3055,5544,5545],{"class":3168},"AddOrUpdate",[3055,5547,5548],{"class":3069},"(\n",[3055,5550,5551,5554,5556,5559],{"class":3057,"line":3119},[3055,5552,5553],{"class":3126},"    key",[3055,5555,5292],{"class":3069},[3055,5557,5558],{"class":3302},"\"counter\"",[3055,5560,5254],{"class":3069},[3055,5562,5563,5566,5568,5570,5573],{"class":3057,"line":3148},[3055,5564,5565],{"class":3126},"    addValue",[3055,5567,5292],{"class":3069},[3055,5569,3433],{"class":3175},[3055,5571,5572],{"class":3069},",                    ",[3055,5574,5575],{"class":3156},"// Якщо ключа немає → додати 1\n",[3055,5577,5578,5581,5584,5586,5588,5591,5593,5595,5597,5599],{"class":3057,"line":3153},[3055,5579,5580],{"class":3126},"    updateValueFactory",[3055,5582,5583],{"class":3069},": (",[3055,5585,3707],{"class":3126},[3055,5587,2971],{"class":3069},[3055,5589,5590],{"class":3126},"oldValue",[3055,5592,5271],{"class":3069},[3055,5594,5590],{"class":3126},[3055,5596,3261],{"class":3069},[3055,5598,3433],{"class":3175},[3055,5600,5601],{"class":3156},"  // Якщо є → інкремент\n",[3055,5603,5604],{"class":3057,"line":3160},[3055,5605,3324],{"class":3069},[3055,5607,5608,5610,5612,5614,5616,5619,5621],{"class":3057,"line":3192},[3055,5609,3292],{"class":3126},[3055,5611,3080],{"class":3069},[3055,5613,3297],{"class":3168},[3055,5615,3172],{"class":3069},[3055,5617,5618],{"class":3126},"result1",[3055,5620,3266],{"class":3069},[3055,5622,5623],{"class":3156},"// 1 (додано)\n",[3055,5625,5626],{"class":3057,"line":3198},[3055,5627,3116],{"emptyLinePlaceholder":3115},[3055,5629,5630,5632,5635,5637,5639,5641,5643,5645,5647,5649,5651,5654,5656,5658,5660,5662,5664,5666,5668],{"class":3057,"line":3235},[3055,5631,3142],{"class":3122},[3055,5633,5634],{"class":3126}," result2",[3055,5636,3130],{"class":3069},[3055,5638,4678],{"class":3126},[3055,5640,3080],{"class":3069},[3055,5642,5545],{"class":3168},[3055,5644,3172],{"class":3069},[3055,5646,5558],{"class":3302},[3055,5648,2971],{"class":3069},[3055,5650,3433],{"class":3175},[3055,5652,5653],{"class":3069},", (",[3055,5655,3707],{"class":3126},[3055,5657,2971],{"class":3069},[3055,5659,5590],{"class":3126},[3055,5661,5271],{"class":3069},[3055,5663,5590],{"class":3126},[3055,5665,3261],{"class":3069},[3055,5667,3433],{"class":3175},[3055,5669,3324],{"class":3069},[3055,5671,5672,5674,5676,5678,5680,5683,5685],{"class":3057,"line":3241},[3055,5673,3292],{"class":3126},[3055,5675,3080],{"class":3069},[3055,5677,3297],{"class":3168},[3055,5679,3172],{"class":3069},[3055,5681,5682],{"class":3126},"result2",[3055,5684,3266],{"class":3069},[3055,5686,5687],{"class":3156},"// 2 (оновлено)\n",[3055,5689,5690],{"class":3057,"line":3272},[3055,5691,3116],{"emptyLinePlaceholder":3115},[3055,5693,5694],{"class":3057,"line":3278},[3055,5695,5696],{"class":3156},"// Варіант 2: з factoryArgument (без closure)\n",[3055,5698,5699,5701,5704,5706,5708,5710,5712],{"class":3057,"line":3284},[3055,5700,3142],{"class":3122},[3055,5702,5703],{"class":3126}," result3",[3055,5705,3130],{"class":3069},[3055,5707,4678],{"class":3126},[3055,5709,3080],{"class":3069},[3055,5711,5545],{"class":3168},[3055,5713,5548],{"class":3069},[3055,5715,5716,5718,5720,5722],{"class":3057,"line":3289},[3055,5717,5553],{"class":3126},[3055,5719,5292],{"class":3069},[3055,5721,5558],{"class":3302},[3055,5723,5254],{"class":3069},[3055,5725,5726,5729,5731,5734,5736,5738,5740,5742,5744,5746],{"class":3057,"line":3327},[3055,5727,5728],{"class":3126},"    addValueFactory",[3055,5730,5292],{"class":3069},[3055,5732,5733],{"class":3122},"static",[3055,5735,3204],{"class":3069},[3055,5737,3707],{"class":3126},[3055,5739,2971],{"class":3069},[3055,5741,5268],{"class":3126},[3055,5743,5271],{"class":3069},[3055,5745,5268],{"class":3126},[3055,5747,5254],{"class":3069},[3055,5749,5750,5752,5754,5756,5758,5760,5762,5764,5766,5768,5770,5772,5774,5776],{"class":3057,"line":3333},[3055,5751,5580],{"class":3126},[3055,5753,5292],{"class":3069},[3055,5755,5733],{"class":3122},[3055,5757,3204],{"class":3069},[3055,5759,3707],{"class":3126},[3055,5761,2971],{"class":3069},[3055,5763,5590],{"class":3126},[3055,5765,2971],{"class":3069},[3055,5767,5268],{"class":3126},[3055,5769,5271],{"class":3069},[3055,5771,5590],{"class":3126},[3055,5773,3261],{"class":3069},[3055,5775,5268],{"class":3126},[3055,5777,5254],{"class":3069},[3055,5779,5780,5782,5784],{"class":3057,"line":3338},[3055,5781,5289],{"class":3126},[3055,5783,5292],{"class":3069},[3055,5785,5786],{"class":3175},"10\n",[3055,5788,5789],{"class":3057,"line":3755},[3055,5790,3324],{"class":3069},[3055,5792,5793,5795,5797,5799,5801,5804,5806],{"class":3057,"line":3760},[3055,5794,3292],{"class":3126},[3055,5796,3080],{"class":3069},[3055,5798,3297],{"class":3168},[3055,5800,3172],{"class":3069},[3055,5802,5803],{"class":3126},"result3",[3055,5805,3266],{"class":3069},[3055,5807,5808],{"class":3156},"// 12 (2 + 10)\n",[2964,5810,5811,3490],{},[2977,5812,5813],{},"Use case: Thread-safe counter",[3044,5815,5817],{"className":3046,"code":5816,"language":3049,"meta":3051,"style":3051},"var counters = new ConcurrentDictionary\u003Cstring, int>();\n\n// 1000 потоків інкрементують різні лічильники\nParallel.For(0, 1000, i =>\n{\n    string key = $\"counter-{i % 10}\";  // 10 різних лічильників\n    counters.AddOrUpdate(key, 1, (k, v) => v + 1);\n});\n\nforeach (var kvp in counters)\n{\n    Console.WriteLine($\"{kvp.Key}: {kvp.Value}\");\n}\n// Кожен лічильник має значення 100 (1000 / 10)\n",[2968,5818,5819,5842,5846,5851,5873,5877,5908,5945,5949,5953,5972,5976,6018,6022],{"__ignoreMap":3051},[3055,5820,5821,5823,5826,5828,5830,5832,5834,5836,5838,5840],{"class":3057,"line":3058},[3055,5822,3123],{"class":3122},[3055,5824,5825],{"class":3126}," counters",[3055,5827,3130],{"class":3069},[3055,5829,3133],{"class":3122},[3055,5831,4646],{"class":3065},[3055,5833,3139],{"class":3069},[3055,5835,3580],{"class":3122},[3055,5837,2971],{"class":3069},[3055,5839,3142],{"class":3122},[3055,5841,3145],{"class":3069},[3055,5843,5844],{"class":3057,"line":3073},[3055,5845,3116],{"emptyLinePlaceholder":3115},[3055,5847,5848],{"class":3057,"line":3093},[3055,5849,5850],{"class":3156},"// 1000 потоків інкрементують різні лічильники\n",[3055,5852,5853,5855,5857,5859,5861,5863,5865,5867,5869,5871],{"class":3057,"line":3112},[3055,5854,3163],{"class":3126},[3055,5856,3080],{"class":3069},[3055,5858,3169],{"class":3168},[3055,5860,3172],{"class":3069},[3055,5862,3176],{"class":3175},[3055,5864,2971],{"class":3069},[3055,5866,3225],{"class":3175},[3055,5868,2971],{"class":3069},[3055,5870,3186],{"class":3126},[3055,5872,3189],{"class":3069},[3055,5874,5875],{"class":3057,"line":3119},[3055,5876,3195],{"class":3069},[3055,5878,5879,5882,5884,5886,5889,5891,5893,5896,5899,5901,5903,5905],{"class":3057,"line":3148},[3055,5880,5881],{"class":3122},"    string",[3055,5883,3673],{"class":3126},[3055,5885,3130],{"class":3069},[3055,5887,5888],{"class":3302},"$\"counter-",[3055,5890,3307],{"class":3306},[3055,5892,3186],{"class":3126},[3055,5894,5895],{"class":3069}," %",[3055,5897,5898],{"class":3175}," 10",[3055,5900,3318],{"class":3306},[3055,5902,3321],{"class":3302},[3055,5904,3465],{"class":3069},[3055,5906,5907],{"class":3156},"// 10 різних лічильників\n",[3055,5909,5910,5913,5915,5917,5919,5921,5923,5925,5927,5930,5932,5935,5937,5939,5941,5943],{"class":3057,"line":3153},[3055,5911,5912],{"class":3126},"    counters",[3055,5914,3080],{"class":3069},[3055,5916,5545],{"class":3168},[3055,5918,3172],{"class":3069},[3055,5920,3707],{"class":3126},[3055,5922,2971],{"class":3069},[3055,5924,3433],{"class":3175},[3055,5926,5653],{"class":3069},[3055,5928,5929],{"class":3126},"k",[3055,5931,2971],{"class":3069},[3055,5933,5934],{"class":3126},"v",[3055,5936,5271],{"class":3069},[3055,5938,5934],{"class":3126},[3055,5940,3261],{"class":3069},[3055,5942,3433],{"class":3175},[3055,5944,3324],{"class":3069},[3055,5946,5947],{"class":3057,"line":3160},[3055,5948,3281],{"class":3069},[3055,5950,5951],{"class":3057,"line":3192},[3055,5952,3116],{"emptyLinePlaceholder":3115},[3055,5954,5955,5958,5960,5962,5965,5968,5970],{"class":3057,"line":3198},[3055,5956,5957],{"class":3061},"foreach",[3055,5959,3204],{"class":3069},[3055,5961,3123],{"class":3122},[3055,5963,5964],{"class":3126}," kvp",[3055,5966,5967],{"class":3061}," in",[3055,5969,5825],{"class":3126},[3055,5971,3384],{"class":3069},[3055,5973,5974],{"class":3057,"line":3235},[3055,5975,3195],{"class":3069},[3055,5977,5978,5980,5982,5984,5986,5989,5991,5994,5996,5999,6001,6003,6005,6007,6009,6012,6014,6016],{"class":3057,"line":3241},[3055,5979,3763],{"class":3126},[3055,5981,3080],{"class":3069},[3055,5983,3297],{"class":3168},[3055,5985,3172],{"class":3069},[3055,5987,5988],{"class":3302},"$\"",[3055,5990,3307],{"class":3306},[3055,5992,5993],{"class":3126},"kvp",[3055,5995,3080],{"class":3306},[3055,5997,5998],{"class":3126},"Key",[3055,6000,3318],{"class":3306},[3055,6002,5292],{"class":3302},[3055,6004,3307],{"class":3306},[3055,6006,5993],{"class":3126},[3055,6008,3080],{"class":3306},[3055,6010,6011],{"class":3126},"Value",[3055,6013,3318],{"class":3306},[3055,6015,3321],{"class":3302},[3055,6017,3324],{"class":3069},[3055,6019,6020],{"class":3057,"line":3272},[3055,6021,3484],{"class":3069},[3055,6023,6024],{"class":3057,"line":3278},[3055,6025,6026],{"class":3156},"// Кожен лічильник має значення 100 (1000 / 10)\n",[4624,6028,6030],{"id":6029},"tryupdate-умовне-оновлення","TryUpdate — Умовне Оновлення",[3044,6032,6035],{"className":3046,"code":6033,"filename":6034,"language":3049,"meta":3050,"style":3051},"var dict = new ConcurrentDictionary\u003Cstring, int>();\ndict.TryAdd(\"balance\", 1000);\n\n// Спроба оновити ТІЛЬКИ якщо поточне значення = 1000\nbool updated = dict.TryUpdate(\n    key: \"balance\",\n    newValue: 900,\n    comparisonValue: 1000  // Очікуване поточне значення\n);\nConsole.WriteLine($\"Updated: {updated}\");  // true\nConsole.WriteLine($\"Balance: {dict[\"balance\"]}\");  // 900\n\n// Повторна спроба — не вдасться (значення вже 900, не 1000)\nupdated = dict.TryUpdate(\"balance\", 800, 1000);\nConsole.WriteLine($\"Updated: {updated}\");  // false\nConsole.WriteLine($\"Balance: {dict[\"balance\"]}\");  // 900 (не змінилось)\n","TryUpdate.cs",[2968,6036,6037,6059,6078,6082,6087,6105,6115,6127,6139,6143,6169,6199,6203,6208,6235,6259],{"__ignoreMap":3051},[3055,6038,6039,6041,6043,6045,6047,6049,6051,6053,6055,6057],{"class":3057,"line":3058},[3055,6040,3123],{"class":3122},[3055,6042,3568],{"class":3126},[3055,6044,3130],{"class":3069},[3055,6046,3133],{"class":3122},[3055,6048,4646],{"class":3065},[3055,6050,3139],{"class":3069},[3055,6052,3580],{"class":3122},[3055,6054,2971],{"class":3069},[3055,6056,3142],{"class":3122},[3055,6058,3145],{"class":3069},[3055,6060,6061,6063,6065,6067,6069,6072,6074,6076],{"class":3057,"line":3073},[3055,6062,4678],{"class":3126},[3055,6064,3080],{"class":3069},[3055,6066,4683],{"class":3168},[3055,6068,3172],{"class":3069},[3055,6070,6071],{"class":3302},"\"balance\"",[3055,6073,2971],{"class":3069},[3055,6075,3225],{"class":3175},[3055,6077,3324],{"class":3069},[3055,6079,6080],{"class":3057,"line":3093},[3055,6081,3116],{"emptyLinePlaceholder":3115},[3055,6083,6084],{"class":3057,"line":3112},[3055,6085,6086],{"class":3156},"// Спроба оновити ТІЛЬКИ якщо поточне значення = 1000\n",[3055,6088,6089,6091,6094,6096,6098,6100,6103],{"class":3057,"line":3119},[3055,6090,4670],{"class":3122},[3055,6092,6093],{"class":3126}," updated",[3055,6095,3130],{"class":3069},[3055,6097,4678],{"class":3126},[3055,6099,3080],{"class":3069},[3055,6101,6102],{"class":3168},"TryUpdate",[3055,6104,5548],{"class":3069},[3055,6106,6107,6109,6111,6113],{"class":3057,"line":3148},[3055,6108,5553],{"class":3126},[3055,6110,5292],{"class":3069},[3055,6112,6071],{"class":3302},[3055,6114,5254],{"class":3069},[3055,6116,6117,6120,6122,6125],{"class":3057,"line":3153},[3055,6118,6119],{"class":3126},"    newValue",[3055,6121,5292],{"class":3069},[3055,6123,6124],{"class":3175},"900",[3055,6126,5254],{"class":3069},[3055,6128,6129,6132,6134,6136],{"class":3057,"line":3160},[3055,6130,6131],{"class":3126},"    comparisonValue",[3055,6133,5292],{"class":3069},[3055,6135,3225],{"class":3175},[3055,6137,6138],{"class":3156},"  // Очікуване поточне значення\n",[3055,6140,6141],{"class":3057,"line":3192},[3055,6142,3324],{"class":3069},[3055,6144,6145,6147,6149,6151,6153,6156,6158,6161,6163,6165,6167],{"class":3057,"line":3198},[3055,6146,3292],{"class":3126},[3055,6148,3080],{"class":3069},[3055,6150,3297],{"class":3168},[3055,6152,3172],{"class":3069},[3055,6154,6155],{"class":3302},"$\"Updated: ",[3055,6157,3307],{"class":3306},[3055,6159,6160],{"class":3126},"updated",[3055,6162,3318],{"class":3306},[3055,6164,3321],{"class":3302},[3055,6166,3266],{"class":3069},[3055,6168,4722],{"class":3156},[3055,6170,6171,6173,6175,6177,6179,6182,6184,6186,6188,6190,6192,6194,6196],{"class":3057,"line":3235},[3055,6172,3292],{"class":3126},[3055,6174,3080],{"class":3069},[3055,6176,3297],{"class":3168},[3055,6178,3172],{"class":3069},[3055,6180,6181],{"class":3302},"$\"Balance: ",[3055,6183,3307],{"class":3306},[3055,6185,4678],{"class":3126},[3055,6187,3454],{"class":3306},[3055,6189,6071],{"class":3302},[3055,6191,4807],{"class":3306},[3055,6193,3321],{"class":3302},[3055,6195,3266],{"class":3069},[3055,6197,6198],{"class":3156},"// 900\n",[3055,6200,6201],{"class":3057,"line":3241},[3055,6202,3116],{"emptyLinePlaceholder":3115},[3055,6204,6205],{"class":3057,"line":3272},[3055,6206,6207],{"class":3156},"// Повторна спроба — не вдасться (значення вже 900, не 1000)\n",[3055,6209,6210,6212,6214,6216,6218,6220,6222,6224,6226,6229,6231,6233],{"class":3057,"line":3278},[3055,6211,6160],{"class":3126},[3055,6213,3130],{"class":3069},[3055,6215,4678],{"class":3126},[3055,6217,3080],{"class":3069},[3055,6219,6102],{"class":3168},[3055,6221,3172],{"class":3069},[3055,6223,6071],{"class":3302},[3055,6225,2971],{"class":3069},[3055,6227,6228],{"class":3175},"800",[3055,6230,2971],{"class":3069},[3055,6232,3225],{"class":3175},[3055,6234,3324],{"class":3069},[3055,6236,6237,6239,6241,6243,6245,6247,6249,6251,6253,6255,6257],{"class":3057,"line":3284},[3055,6238,3292],{"class":3126},[3055,6240,3080],{"class":3069},[3055,6242,3297],{"class":3168},[3055,6244,3172],{"class":3069},[3055,6246,6155],{"class":3302},[3055,6248,3307],{"class":3306},[3055,6250,6160],{"class":3126},[3055,6252,3318],{"class":3306},[3055,6254,3321],{"class":3302},[3055,6256,3266],{"class":3069},[3055,6258,4779],{"class":3156},[3055,6260,6261,6263,6265,6267,6269,6271,6273,6275,6277,6279,6281,6283,6285],{"class":3057,"line":3289},[3055,6262,3292],{"class":3126},[3055,6264,3080],{"class":3069},[3055,6266,3297],{"class":3168},[3055,6268,3172],{"class":3069},[3055,6270,6181],{"class":3302},[3055,6272,3307],{"class":3306},[3055,6274,4678],{"class":3126},[3055,6276,3454],{"class":3306},[3055,6278,6071],{"class":3302},[3055,6280,4807],{"class":3306},[3055,6282,3321],{"class":3302},[3055,6284,3266],{"class":3069},[3055,6286,6287],{"class":3156},"// 900 (не змінилось)\n",[2964,6289,6290,3490],{},[2977,6291,6292],{},"Use case: Optimistic concurrency",[3044,6294,6296],{"className":3046,"code":6295,"language":3049,"meta":3051,"style":3051},"// Банківська транзакція з retry\nbool Withdraw(ConcurrentDictionary\u003Cstring, decimal> accounts, string accountId, decimal amount)\n{\n    while (true)\n    {\n        if (!accounts.TryGetValue(accountId, out decimal currentBalance))\n            return false;  // Рахунок не існує\n\n        if (currentBalance \u003C amount)\n            return false;  // Недостатньо коштів\n\n        decimal newBalance = currentBalance - amount;\n\n        // Спроба оновити (CAS pattern)\n        if (accounts.TryUpdate(accountId, newBalance, currentBalance))\n            return true;  // Успіх!\n\n        // Хтось інший змінив balance між TryGetValue та TryUpdate → retry\n    }\n}\n",[2968,6297,6298,6303,6345,6349,6361,6365,6396,6409,6413,6429,6440,6444,6463,6467,6472,6499,6511,6515,6520,6524],{"__ignoreMap":3051},[3055,6299,6300],{"class":3057,"line":3058},[3055,6301,6302],{"class":3156},"// Банківська транзакція з retry\n",[3055,6304,6305,6307,6310,6312,6314,6316,6318,6320,6323,6326,6329,6331,6333,6336,6338,6340,6343],{"class":3057,"line":3073},[3055,6306,4670],{"class":3122},[3055,6308,6309],{"class":3168}," Withdraw",[3055,6311,3172],{"class":3069},[3055,6313,4274],{"class":3065},[3055,6315,3139],{"class":3069},[3055,6317,3580],{"class":3122},[3055,6319,2971],{"class":3069},[3055,6321,6322],{"class":3122},"decimal",[3055,6324,6325],{"class":3069},"> ",[3055,6327,6328],{"class":3126},"accounts",[3055,6330,2971],{"class":3069},[3055,6332,3580],{"class":3122},[3055,6334,6335],{"class":3126}," accountId",[3055,6337,2971],{"class":3069},[3055,6339,6322],{"class":3122},[3055,6341,6342],{"class":3126}," amount",[3055,6344,3384],{"class":3069},[3055,6346,6347],{"class":3057,"line":3093},[3055,6348,3195],{"class":3069},[3055,6350,6351,6354,6356,6359],{"class":3057,"line":3112},[3055,6352,6353],{"class":3061},"    while",[3055,6355,3204],{"class":3069},[3055,6357,6358],{"class":3122},"true",[3055,6360,3384],{"class":3069},[3055,6362,6363],{"class":3057,"line":3119},[3055,6364,3238],{"class":3069},[3055,6366,6367,6370,6373,6375,6377,6379,6381,6384,6386,6388,6391,6394],{"class":3057,"line":3148},[3055,6368,6369],{"class":3061},"        if",[3055,6371,6372],{"class":3069}," (!",[3055,6374,6328],{"class":3126},[3055,6376,3080],{"class":3069},[3055,6378,4897],{"class":3168},[3055,6380,3172],{"class":3069},[3055,6382,6383],{"class":3126},"accountId",[3055,6385,2971],{"class":3069},[3055,6387,4906],{"class":3122},[3055,6389,6390],{"class":3122}," decimal",[3055,6392,6393],{"class":3126}," currentBalance",[3055,6395,4915],{"class":3069},[3055,6397,6398,6401,6404,6406],{"class":3057,"line":3153},[3055,6399,6400],{"class":3061},"            return",[3055,6402,6403],{"class":3122}," false",[3055,6405,3465],{"class":3069},[3055,6407,6408],{"class":3156},"// Рахунок не існує\n",[3055,6410,6411],{"class":3057,"line":3160},[3055,6412,3116],{"emptyLinePlaceholder":3115},[3055,6414,6415,6417,6419,6422,6424,6427],{"class":3057,"line":3192},[3055,6416,6369],{"class":3061},[3055,6418,3204],{"class":3069},[3055,6420,6421],{"class":3126},"currentBalance",[3055,6423,3222],{"class":3069},[3055,6425,6426],{"class":3126},"amount",[3055,6428,3384],{"class":3069},[3055,6430,6431,6433,6435,6437],{"class":3057,"line":3198},[3055,6432,6400],{"class":3061},[3055,6434,6403],{"class":3122},[3055,6436,3465],{"class":3069},[3055,6438,6439],{"class":3156},"// Недостатньо коштів\n",[3055,6441,6442],{"class":3057,"line":3235},[3055,6443,3116],{"emptyLinePlaceholder":3115},[3055,6445,6446,6449,6452,6454,6456,6459,6461],{"class":3057,"line":3241},[3055,6447,6448],{"class":3122},"        decimal",[3055,6450,6451],{"class":3126}," newBalance",[3055,6453,3130],{"class":3069},[3055,6455,6421],{"class":3126},[3055,6457,6458],{"class":3069}," - ",[3055,6460,6426],{"class":3126},[3055,6462,3070],{"class":3069},[3055,6464,6465],{"class":3057,"line":3272},[3055,6466,3116],{"emptyLinePlaceholder":3115},[3055,6468,6469],{"class":3057,"line":3278},[3055,6470,6471],{"class":3156},"        // Спроба оновити (CAS pattern)\n",[3055,6473,6474,6476,6478,6480,6482,6484,6486,6488,6490,6493,6495,6497],{"class":3057,"line":3284},[3055,6475,6369],{"class":3061},[3055,6477,3204],{"class":3069},[3055,6479,6328],{"class":3126},[3055,6481,3080],{"class":3069},[3055,6483,6102],{"class":3168},[3055,6485,3172],{"class":3069},[3055,6487,6383],{"class":3126},[3055,6489,2971],{"class":3069},[3055,6491,6492],{"class":3126},"newBalance",[3055,6494,2971],{"class":3069},[3055,6496,6421],{"class":3126},[3055,6498,4915],{"class":3069},[3055,6500,6501,6503,6506,6508],{"class":3057,"line":3289},[3055,6502,6400],{"class":3061},[3055,6504,6505],{"class":3122}," true",[3055,6507,3465],{"class":3069},[3055,6509,6510],{"class":3156},"// Успіх!\n",[3055,6512,6513],{"class":3057,"line":3327},[3055,6514,3116],{"emptyLinePlaceholder":3115},[3055,6516,6517],{"class":3057,"line":3333},[3055,6518,6519],{"class":3156},"        // Хтось інший змінив balance між TryGetValue та TryUpdate → retry\n",[3055,6521,6522],{"class":3057,"line":3338},[3055,6523,3275],{"class":3069},[3055,6525,6526],{"class":3057,"line":3755},[3055,6527,3484],{"class":3069},[4624,6529,6531],{"id":6530},"tryremove-видалити-та-отримати-значення","TryRemove — Видалити та Отримати Значення",[3044,6533,6536],{"className":3046,"code":6534,"filename":6535,"language":3049,"meta":3050,"style":3051},"var dict = new ConcurrentDictionary\u003Cstring, int>();\ndict.TryAdd(\"key1\", 100);\n\n// Видалити та отримати значення\nif (dict.TryRemove(\"key1\", out int removedValue))\n{\n    Console.WriteLine($\"Removed: {removedValue}\");  // 100\n}\n\n// Повторна спроба — не вдасться\nif (!dict.TryRemove(\"key1\", out _))\n{\n    Console.WriteLine(\"Key not found\");\n}\n","TryRemove.cs",[2968,6537,6538,6560,6578,6582,6587,6615,6619,6645,6649,6653,6658,6683,6687,6702],{"__ignoreMap":3051},[3055,6539,6540,6542,6544,6546,6548,6550,6552,6554,6556,6558],{"class":3057,"line":3058},[3055,6541,3123],{"class":3122},[3055,6543,3568],{"class":3126},[3055,6545,3130],{"class":3069},[3055,6547,3133],{"class":3122},[3055,6549,4646],{"class":3065},[3055,6551,3139],{"class":3069},[3055,6553,3580],{"class":3122},[3055,6555,2971],{"class":3069},[3055,6557,3142],{"class":3122},[3055,6559,3145],{"class":3069},[3055,6561,6562,6564,6566,6568,6570,6572,6574,6576],{"class":3057,"line":3073},[3055,6563,4678],{"class":3126},[3055,6565,3080],{"class":3069},[3055,6567,4683],{"class":3168},[3055,6569,3172],{"class":3069},[3055,6571,4688],{"class":3302},[3055,6573,2971],{"class":3069},[3055,6575,4693],{"class":3175},[3055,6577,3324],{"class":3069},[3055,6579,6580],{"class":3057,"line":3093},[3055,6581,3116],{"emptyLinePlaceholder":3115},[3055,6583,6584],{"class":3057,"line":3112},[3055,6585,6586],{"class":3156},"// Видалити та отримати значення\n",[3055,6588,6589,6591,6593,6595,6597,6600,6602,6604,6606,6608,6610,6613],{"class":3057,"line":3119},[3055,6590,4888],{"class":3061},[3055,6592,3204],{"class":3069},[3055,6594,4678],{"class":3126},[3055,6596,3080],{"class":3069},[3055,6598,6599],{"class":3168},"TryRemove",[3055,6601,3172],{"class":3069},[3055,6603,4688],{"class":3302},[3055,6605,2971],{"class":3069},[3055,6607,4906],{"class":3122},[3055,6609,4909],{"class":3122},[3055,6611,6612],{"class":3126}," removedValue",[3055,6614,4915],{"class":3069},[3055,6616,6617],{"class":3057,"line":3148},[3055,6618,3195],{"class":3069},[3055,6620,6621,6623,6625,6627,6629,6632,6634,6637,6639,6641,6643],{"class":3057,"line":3153},[3055,6622,3763],{"class":3126},[3055,6624,3080],{"class":3069},[3055,6626,3297],{"class":3168},[3055,6628,3172],{"class":3069},[3055,6630,6631],{"class":3302},"$\"Removed: ",[3055,6633,3307],{"class":3306},[3055,6635,6636],{"class":3126},"removedValue",[3055,6638,3318],{"class":3306},[3055,6640,3321],{"class":3302},[3055,6642,3266],{"class":3069},[3055,6644,5315],{"class":3156},[3055,6646,6647],{"class":3057,"line":3160},[3055,6648,3484],{"class":3069},[3055,6650,6651],{"class":3057,"line":3192},[3055,6652,3116],{"emptyLinePlaceholder":3115},[3055,6654,6655],{"class":3057,"line":3198},[3055,6656,6657],{"class":3156},"// Повторна спроба — не вдасться\n",[3055,6659,6660,6662,6664,6666,6668,6670,6672,6674,6676,6678,6681],{"class":3057,"line":3235},[3055,6661,4888],{"class":3061},[3055,6663,6372],{"class":3069},[3055,6665,4678],{"class":3126},[3055,6667,3080],{"class":3069},[3055,6669,6599],{"class":3168},[3055,6671,3172],{"class":3069},[3055,6673,4688],{"class":3302},[3055,6675,2971],{"class":3069},[3055,6677,4906],{"class":3122},[3055,6679,6680],{"class":3126}," _",[3055,6682,4915],{"class":3069},[3055,6684,6685],{"class":3057,"line":3241},[3055,6686,3195],{"class":3069},[3055,6688,6689,6691,6693,6695,6697,6700],{"class":3057,"line":3272},[3055,6690,3763],{"class":3126},[3055,6692,3080],{"class":3069},[3055,6694,3297],{"class":3168},[3055,6696,3172],{"class":3069},[3055,6698,6699],{"class":3302},"\"Key not found\"",[3055,6701,3324],{"class":3069},[3055,6703,6704],{"class":3057,"line":3278},[3055,6705,3484],{"class":3069},[3032,6707,6709],{"id":6708},"практичний-приклад-thread-safe-cache","Практичний Приклад: Thread-Safe Cache",[3044,6711,6714],{"className":3046,"code":6712,"filename":6713,"language":3049,"meta":3050,"style":3051},"using System;\nusing System.Collections.Concurrent;\nusing System.Threading;\n\npublic class ThreadSafeCache\u003CTKey, TValue> where TKey : notnull\n{\n    private readonly ConcurrentDictionary\u003CTKey, CacheEntry> _cache = new();\n    private readonly TimeSpan _defaultTtl;\n\n    private record CacheEntry(TValue Value, DateTime ExpiresAt);\n\n    public ThreadSafeCache(TimeSpan defaultTtl)\n    {\n        _defaultTtl = defaultTtl;\n    }\n\n    public bool TryGet(TKey key, out TValue? value)\n    {\n        if (_cache.TryGetValue(key, out var entry))\n        {\n            if (entry.ExpiresAt > DateTime.UtcNow)\n            {\n                value = entry.Value;\n                return true;\n            }\n\n            // Expired → видаляємо\n            _cache.TryRemove(key, out _);\n        }\n\n        value = default;\n        return false;\n    }\n\n    public void Set(TKey key, TValue value, TimeSpan? ttl = null)\n    {\n        var expiresAt = DateTime.UtcNow + (ttl ?? _defaultTtl);\n        var entry = new CacheEntry(value, expiresAt);\n\n        _cache[key] = entry;  // AddOrUpdate через indexer\n    }\n\n    public TValue GetOrAdd(TKey key, Func\u003CTKey, TValue> valueFactory, TimeSpan? ttl = null)\n    {\n        var expiresAt = DateTime.UtcNow + (ttl ?? _defaultTtl);\n\n        var entry = _cache.GetOrAdd(key, k =>\n        {\n            var value = valueFactory(k);\n            return new CacheEntry(value, expiresAt);\n        });\n\n        // Перевірка expiration\n        if (entry.ExpiresAt \u003C= DateTime.UtcNow)\n        {\n            // Expired → видаляємо та рекурсивно викликаємо знову\n            _cache.TryRemove(key, out _);\n            return GetOrAdd(key, valueFactory, ttl);\n        }\n\n        return entry.Value;\n    }\n\n    public void Clear() => _cache.Clear();\n\n    public int Count => _cache.Count;\n}\n\n// Використання:\nvar cache = new ThreadSafeCache\u003Cstring, string>(TimeSpan.FromSeconds(10));\n\n// 100 потоків одночасно працюють з кешем\nParallel.For(0, 100, i =>\n{\n    string key = $\"key-{i % 10}\";  // 10 різних ключів\n\n    string value = cache.GetOrAdd(key, k =>\n    {\n        Console.WriteLine($\"[Thread {i}] Computing {k}...\");\n        Thread.Sleep(100);  // Симуляція дорогої операції\n        return $\"value-{k}\";\n    });\n\n    Console.WriteLine($\"[Thread {i}] Got: {value}\");\n});\n\n// Тільки 10 обчислень (по одному на ключ), решта взяли з кешу\n","ThreadSafeCache.cs",[2968,6715,6716,6724,6741,6753,6757,6791,6795,6825,6839,6843,6870,6874,6891,6895,6907,6911,6915,6945,6949,6977,6981,7008,7013,7028,7037,7042,7046,7051,7072,7076,7080,7093,7102,7107,7112,7150,7155,7185,7209,7214,7233,7238,7243,7291,7296,7321,7326,7351,7356,7374,7394,7400,7405,7411,7435,7440,7446,7467,7488,7493,7498,7511,7516,7521,7543,7548,7569,7574,7579,7585,7624,7629,7635,7658,7663,7691,7696,7722,7727,7760,7780,7798,7803,7808,7840,7845,7850],{"__ignoreMap":3051},[3055,6717,6718,6720,6722],{"class":3057,"line":3058},[3055,6719,3062],{"class":3061},[3055,6721,3066],{"class":3065},[3055,6723,3070],{"class":3069},[3055,6725,6726,6728,6730,6732,6734,6736,6739],{"class":3057,"line":3073},[3055,6727,3062],{"class":3061},[3055,6729,3066],{"class":3065},[3055,6731,3080],{"class":3069},[3055,6733,3083],{"class":3065},[3055,6735,3080],{"class":3069},[3055,6737,6738],{"class":3065},"Concurrent",[3055,6740,3070],{"class":3069},[3055,6742,6743,6745,6747,6749,6751],{"class":3057,"line":3093},[3055,6744,3062],{"class":3061},[3055,6746,3066],{"class":3065},[3055,6748,3080],{"class":3069},[3055,6750,3102],{"class":3065},[3055,6752,3070],{"class":3069},[3055,6754,6755],{"class":3057,"line":3112},[3055,6756,3116],{"emptyLinePlaceholder":3115},[3055,6758,6759,6761,6764,6767,6769,6772,6774,6777,6779,6782,6785,6788],{"class":3057,"line":3119},[3055,6760,3367],{"class":3122},[3055,6762,6763],{"class":3122}," class",[3055,6765,6766],{"class":3065}," ThreadSafeCache",[3055,6768,3139],{"class":3069},[3055,6770,6771],{"class":3065},"TKey",[3055,6773,2971],{"class":3069},[3055,6775,6776],{"class":3065},"TValue",[3055,6778,6325],{"class":3069},[3055,6780,6781],{"class":3122},"where",[3055,6783,6784],{"class":3065}," TKey",[3055,6786,6787],{"class":3069}," : ",[3055,6789,6790],{"class":3122},"notnull\n",[3055,6792,6793],{"class":3057,"line":3148},[3055,6794,3195],{"class":3069},[3055,6796,6797,6800,6803,6805,6807,6809,6811,6814,6816,6819,6821,6823],{"class":3057,"line":3153},[3055,6798,6799],{"class":3122},"    private",[3055,6801,6802],{"class":3122}," readonly",[3055,6804,4646],{"class":3065},[3055,6806,3139],{"class":3069},[3055,6808,6771],{"class":3065},[3055,6810,2971],{"class":3069},[3055,6812,6813],{"class":3065},"CacheEntry",[3055,6815,6325],{"class":3069},[3055,6817,6818],{"class":3126},"_cache",[3055,6820,3130],{"class":3069},[3055,6822,3133],{"class":3122},[3055,6824,4071],{"class":3069},[3055,6826,6827,6829,6831,6834,6837],{"class":3057,"line":3160},[3055,6828,6799],{"class":3122},[3055,6830,6802],{"class":3122},[3055,6832,6833],{"class":3065}," TimeSpan",[3055,6835,6836],{"class":3126}," _defaultTtl",[3055,6838,3070],{"class":3069},[3055,6840,6841],{"class":3057,"line":3192},[3055,6842,3116],{"emptyLinePlaceholder":3115},[3055,6844,6845,6847,6850,6853,6855,6857,6860,6862,6865,6868],{"class":3057,"line":3198},[3055,6846,6799],{"class":3122},[3055,6848,6849],{"class":3122}," record",[3055,6851,6852],{"class":3065}," CacheEntry",[3055,6854,3172],{"class":3069},[3055,6856,6776],{"class":3065},[3055,6858,6859],{"class":3126}," Value",[3055,6861,2971],{"class":3069},[3055,6863,6864],{"class":3065},"DateTime",[3055,6866,6867],{"class":3126}," ExpiresAt",[3055,6869,3324],{"class":3069},[3055,6871,6872],{"class":3057,"line":3235},[3055,6873,3116],{"emptyLinePlaceholder":3115},[3055,6875,6876,6879,6881,6883,6886,6889],{"class":3057,"line":3241},[3055,6877,6878],{"class":3122},"    public",[3055,6880,6766],{"class":3168},[3055,6882,3172],{"class":3069},[3055,6884,6885],{"class":3065},"TimeSpan",[3055,6887,6888],{"class":3126}," defaultTtl",[3055,6890,3384],{"class":3069},[3055,6892,6893],{"class":3057,"line":3272},[3055,6894,3238],{"class":3069},[3055,6896,6897,6900,6902,6905],{"class":3057,"line":3278},[3055,6898,6899],{"class":3126},"        _defaultTtl",[3055,6901,3130],{"class":3069},[3055,6903,6904],{"class":3126},"defaultTtl",[3055,6906,3070],{"class":3069},[3055,6908,6909],{"class":3057,"line":3284},[3055,6910,3275],{"class":3069},[3055,6912,6913],{"class":3057,"line":3289},[3055,6914,3116],{"emptyLinePlaceholder":3115},[3055,6916,6917,6919,6922,6925,6927,6929,6931,6933,6935,6938,6941,6943],{"class":3057,"line":3327},[3055,6918,6878],{"class":3122},[3055,6920,6921],{"class":3122}," bool",[3055,6923,6924],{"class":3168}," TryGet",[3055,6926,3172],{"class":3069},[3055,6928,6771],{"class":3065},[3055,6930,3673],{"class":3126},[3055,6932,2971],{"class":3069},[3055,6934,4906],{"class":3122},[3055,6936,6937],{"class":3065}," TValue",[3055,6939,6940],{"class":3069},"? ",[3055,6942,4937],{"class":3126},[3055,6944,3384],{"class":3069},[3055,6946,6947],{"class":3057,"line":3333},[3055,6948,3238],{"class":3069},[3055,6950,6951,6953,6955,6957,6959,6961,6963,6965,6967,6969,6972,6975],{"class":3057,"line":3338},[3055,6952,6369],{"class":3061},[3055,6954,3204],{"class":3069},[3055,6956,6818],{"class":3126},[3055,6958,3080],{"class":3069},[3055,6960,4897],{"class":3168},[3055,6962,3172],{"class":3069},[3055,6964,3707],{"class":3126},[3055,6966,2971],{"class":3069},[3055,6968,4906],{"class":3122},[3055,6970,6971],{"class":3122}," var",[3055,6973,6974],{"class":3126}," entry",[3055,6976,4915],{"class":3069},[3055,6978,6979],{"class":3057,"line":3755},[3055,6980,3665],{"class":3069},[3055,6982,6983,6986,6988,6991,6993,6996,6999,7001,7003,7006],{"class":3057,"line":3760},[3055,6984,6985],{"class":3061},"            if",[3055,6987,3204],{"class":3069},[3055,6989,6990],{"class":3126},"entry",[3055,6992,3080],{"class":3069},[3055,6994,6995],{"class":3126},"ExpiresAt",[3055,6997,6998],{"class":3069}," > ",[3055,7000,6864],{"class":3126},[3055,7002,3080],{"class":3069},[3055,7004,7005],{"class":3126},"UtcNow",[3055,7007,3384],{"class":3069},[3055,7009,7010],{"class":3057,"line":3797},[3055,7011,7012],{"class":3069},"            {\n",[3055,7014,7015,7018,7020,7022,7024,7026],{"class":3057,"line":3826},[3055,7016,7017],{"class":3126},"                value",[3055,7019,3130],{"class":3069},[3055,7021,6990],{"class":3126},[3055,7023,3080],{"class":3069},[3055,7025,6011],{"class":3126},[3055,7027,3070],{"class":3069},[3055,7029,7030,7033,7035],{"class":3057,"line":3831},[3055,7031,7032],{"class":3061},"                return",[3055,7034,6505],{"class":3122},[3055,7036,3070],{"class":3069},[3055,7038,7039],{"class":3057,"line":3836},[3055,7040,7041],{"class":3069},"            }\n",[3055,7043,7044],{"class":3057,"line":3842},[3055,7045,3116],{"emptyLinePlaceholder":3115},[3055,7047,7048],{"class":3057,"line":3848},[3055,7049,7050],{"class":3156},"            // Expired → видаляємо\n",[3055,7052,7053,7056,7058,7060,7062,7064,7066,7068,7070],{"class":3057,"line":3854},[3055,7054,7055],{"class":3126},"            _cache",[3055,7057,3080],{"class":3069},[3055,7059,6599],{"class":3168},[3055,7061,3172],{"class":3069},[3055,7063,3707],{"class":3126},[3055,7065,2971],{"class":3069},[3055,7067,4906],{"class":3122},[3055,7069,6680],{"class":3126},[3055,7071,3324],{"class":3069},[3055,7073,7074],{"class":3057,"line":4603},[3055,7075,3728],{"class":3069},[3055,7077,7078],{"class":3057,"line":4609},[3055,7079,3116],{"emptyLinePlaceholder":3115},[3055,7081,7083,7086,7088,7091],{"class":3057,"line":7082},31,[3055,7084,7085],{"class":3126},"        value",[3055,7087,3130],{"class":3069},[3055,7089,7090],{"class":3122},"default",[3055,7092,3070],{"class":3069},[3055,7094,7096,7098,7100],{"class":3057,"line":7095},32,[3055,7097,5441],{"class":3061},[3055,7099,6403],{"class":3122},[3055,7101,3070],{"class":3069},[3055,7103,7105],{"class":3057,"line":7104},33,[3055,7106,3275],{"class":3069},[3055,7108,7110],{"class":3057,"line":7109},34,[3055,7111,3116],{"emptyLinePlaceholder":3115},[3055,7113,7115,7117,7119,7122,7124,7126,7128,7130,7132,7134,7136,7138,7140,7143,7145,7148],{"class":3057,"line":7114},35,[3055,7116,6878],{"class":3122},[3055,7118,3370],{"class":3122},[3055,7120,7121],{"class":3168}," Set",[3055,7123,3172],{"class":3069},[3055,7125,6771],{"class":3065},[3055,7127,3673],{"class":3126},[3055,7129,2971],{"class":3069},[3055,7131,6776],{"class":3065},[3055,7133,4912],{"class":3126},[3055,7135,2971],{"class":3069},[3055,7137,6885],{"class":3065},[3055,7139,6940],{"class":3069},[3055,7141,7142],{"class":3126},"ttl",[3055,7144,3130],{"class":3069},[3055,7146,7147],{"class":3122},"null",[3055,7149,3384],{"class":3069},[3055,7151,7153],{"class":3057,"line":7152},36,[3055,7154,3238],{"class":3069},[3055,7156,7158,7161,7164,7166,7168,7170,7172,7175,7177,7180,7183],{"class":3057,"line":7157},37,[3055,7159,7160],{"class":3122},"        var",[3055,7162,7163],{"class":3126}," expiresAt",[3055,7165,3130],{"class":3069},[3055,7167,6864],{"class":3126},[3055,7169,3080],{"class":3069},[3055,7171,7005],{"class":3126},[3055,7173,7174],{"class":3069}," + (",[3055,7176,7142],{"class":3126},[3055,7178,7179],{"class":3069}," ?? ",[3055,7181,7182],{"class":3126},"_defaultTtl",[3055,7184,3324],{"class":3069},[3055,7186,7188,7190,7192,7194,7196,7198,7200,7202,7204,7207],{"class":3057,"line":7187},38,[3055,7189,7160],{"class":3122},[3055,7191,6974],{"class":3126},[3055,7193,3130],{"class":3069},[3055,7195,3133],{"class":3122},[3055,7197,6852],{"class":3065},[3055,7199,3172],{"class":3069},[3055,7201,4937],{"class":3126},[3055,7203,2971],{"class":3069},[3055,7205,7206],{"class":3126},"expiresAt",[3055,7208,3324],{"class":3069},[3055,7210,7212],{"class":3057,"line":7211},39,[3055,7213,3116],{"emptyLinePlaceholder":3115},[3055,7215,7217,7220,7222,7224,7226,7228,7230],{"class":3057,"line":7216},40,[3055,7218,7219],{"class":3126},"        _cache",[3055,7221,3454],{"class":3069},[3055,7223,3707],{"class":3126},[3055,7225,3459],{"class":3069},[3055,7227,6990],{"class":3126},[3055,7229,3465],{"class":3069},[3055,7231,7232],{"class":3156},"// AddOrUpdate через indexer\n",[3055,7234,7236],{"class":3057,"line":7235},41,[3055,7237,3275],{"class":3069},[3055,7239,7241],{"class":3057,"line":7240},42,[3055,7242,3116],{"emptyLinePlaceholder":3115},[3055,7244,7246,7248,7250,7253,7255,7257,7259,7261,7264,7266,7268,7270,7272,7274,7277,7279,7281,7283,7285,7287,7289],{"class":3057,"line":7245},43,[3055,7247,6878],{"class":3122},[3055,7249,6937],{"class":3065},[3055,7251,7252],{"class":3168}," GetOrAdd",[3055,7254,3172],{"class":3069},[3055,7256,6771],{"class":3065},[3055,7258,3673],{"class":3126},[3055,7260,2971],{"class":3069},[3055,7262,7263],{"class":3065},"Func",[3055,7265,3139],{"class":3069},[3055,7267,6771],{"class":3065},[3055,7269,2971],{"class":3069},[3055,7271,6776],{"class":3065},[3055,7273,6325],{"class":3069},[3055,7275,7276],{"class":3126},"valueFactory",[3055,7278,2971],{"class":3069},[3055,7280,6885],{"class":3065},[3055,7282,6940],{"class":3069},[3055,7284,7142],{"class":3126},[3055,7286,3130],{"class":3069},[3055,7288,7147],{"class":3122},[3055,7290,3384],{"class":3069},[3055,7292,7294],{"class":3057,"line":7293},44,[3055,7295,3238],{"class":3069},[3055,7297,7299,7301,7303,7305,7307,7309,7311,7313,7315,7317,7319],{"class":3057,"line":7298},45,[3055,7300,7160],{"class":3122},[3055,7302,7163],{"class":3126},[3055,7304,3130],{"class":3069},[3055,7306,6864],{"class":3126},[3055,7308,3080],{"class":3069},[3055,7310,7005],{"class":3126},[3055,7312,7174],{"class":3069},[3055,7314,7142],{"class":3126},[3055,7316,7179],{"class":3069},[3055,7318,7182],{"class":3126},[3055,7320,3324],{"class":3069},[3055,7322,7324],{"class":3057,"line":7323},46,[3055,7325,3116],{"emptyLinePlaceholder":3115},[3055,7327,7329,7331,7333,7335,7337,7339,7341,7343,7345,7347,7349],{"class":3057,"line":7328},47,[3055,7330,7160],{"class":3122},[3055,7332,6974],{"class":3126},[3055,7334,3130],{"class":3069},[3055,7336,6818],{"class":3126},[3055,7338,3080],{"class":3069},[3055,7340,5066],{"class":3168},[3055,7342,3172],{"class":3069},[3055,7344,3707],{"class":3126},[3055,7346,2971],{"class":3069},[3055,7348,5929],{"class":3126},[3055,7350,3189],{"class":3069},[3055,7352,7354],{"class":3057,"line":7353},48,[3055,7355,3665],{"class":3069},[3055,7357,7359,7362,7364,7366,7368,7370,7372],{"class":3057,"line":7358},49,[3055,7360,7361],{"class":3122},"            var",[3055,7363,4912],{"class":3126},[3055,7365,3130],{"class":3069},[3055,7367,7276],{"class":3168},[3055,7369,3172],{"class":3069},[3055,7371,5929],{"class":3126},[3055,7373,3324],{"class":3069},[3055,7375,7377,7379,7382,7384,7386,7388,7390,7392],{"class":3057,"line":7376},50,[3055,7378,6400],{"class":3061},[3055,7380,7381],{"class":3122}," new",[3055,7383,6852],{"class":3065},[3055,7385,3172],{"class":3069},[3055,7387,4937],{"class":3126},[3055,7389,2971],{"class":3069},[3055,7391,7206],{"class":3126},[3055,7393,3324],{"class":3069},[3055,7395,7397],{"class":3057,"line":7396},51,[3055,7398,7399],{"class":3069},"        });\n",[3055,7401,7403],{"class":3057,"line":7402},52,[3055,7404,3116],{"emptyLinePlaceholder":3115},[3055,7406,7408],{"class":3057,"line":7407},53,[3055,7409,7410],{"class":3156},"        // Перевірка expiration\n",[3055,7412,7414,7416,7418,7420,7422,7424,7427,7429,7431,7433],{"class":3057,"line":7413},54,[3055,7415,6369],{"class":3061},[3055,7417,3204],{"class":3069},[3055,7419,6990],{"class":3126},[3055,7421,3080],{"class":3069},[3055,7423,6995],{"class":3126},[3055,7425,7426],{"class":3069}," \u003C= ",[3055,7428,6864],{"class":3126},[3055,7430,3080],{"class":3069},[3055,7432,7005],{"class":3126},[3055,7434,3384],{"class":3069},[3055,7436,7438],{"class":3057,"line":7437},55,[3055,7439,3665],{"class":3069},[3055,7441,7443],{"class":3057,"line":7442},56,[3055,7444,7445],{"class":3156},"            // Expired → видаляємо та рекурсивно викликаємо знову\n",[3055,7447,7449,7451,7453,7455,7457,7459,7461,7463,7465],{"class":3057,"line":7448},57,[3055,7450,7055],{"class":3126},[3055,7452,3080],{"class":3069},[3055,7454,6599],{"class":3168},[3055,7456,3172],{"class":3069},[3055,7458,3707],{"class":3126},[3055,7460,2971],{"class":3069},[3055,7462,4906],{"class":3122},[3055,7464,6680],{"class":3126},[3055,7466,3324],{"class":3069},[3055,7468,7470,7472,7474,7476,7478,7480,7482,7484,7486],{"class":3057,"line":7469},58,[3055,7471,6400],{"class":3061},[3055,7473,7252],{"class":3168},[3055,7475,3172],{"class":3069},[3055,7477,3707],{"class":3126},[3055,7479,2971],{"class":3069},[3055,7481,7276],{"class":3126},[3055,7483,2971],{"class":3069},[3055,7485,7142],{"class":3126},[3055,7487,3324],{"class":3069},[3055,7489,7491],{"class":3057,"line":7490},59,[3055,7492,3728],{"class":3069},[3055,7494,7496],{"class":3057,"line":7495},60,[3055,7497,3116],{"emptyLinePlaceholder":3115},[3055,7499,7501,7503,7505,7507,7509],{"class":3057,"line":7500},61,[3055,7502,5441],{"class":3061},[3055,7504,6974],{"class":3126},[3055,7506,3080],{"class":3069},[3055,7508,6011],{"class":3126},[3055,7510,3070],{"class":3069},[3055,7512,7514],{"class":3057,"line":7513},62,[3055,7515,3275],{"class":3069},[3055,7517,7519],{"class":3057,"line":7518},63,[3055,7520,3116],{"emptyLinePlaceholder":3115},[3055,7522,7524,7526,7528,7531,7534,7536,7538,7541],{"class":3057,"line":7523},64,[3055,7525,6878],{"class":3122},[3055,7527,3370],{"class":3122},[3055,7529,7530],{"class":3168}," Clear",[3055,7532,7533],{"class":3069},"() => ",[3055,7535,6818],{"class":3126},[3055,7537,3080],{"class":3069},[3055,7539,7540],{"class":3168},"Clear",[3055,7542,4071],{"class":3069},[3055,7544,7546],{"class":3057,"line":7545},65,[3055,7547,3116],{"emptyLinePlaceholder":3115},[3055,7549,7551,7553,7555,7558,7561,7563,7565,7567],{"class":3057,"line":7550},66,[3055,7552,6878],{"class":3122},[3055,7554,4909],{"class":3122},[3055,7556,7557],{"class":3126}," Count",[3055,7559,7560],{"class":3069}," => ",[3055,7562,6818],{"class":3126},[3055,7564,3080],{"class":3069},[3055,7566,3315],{"class":3126},[3055,7568,3070],{"class":3069},[3055,7570,7572],{"class":3057,"line":7571},67,[3055,7573,3484],{"class":3069},[3055,7575,7577],{"class":3057,"line":7576},68,[3055,7578,3116],{"emptyLinePlaceholder":3115},[3055,7580,7582],{"class":3057,"line":7581},69,[3055,7583,7584],{"class":3156},"// Використання:\n",[3055,7586,7588,7590,7593,7595,7597,7599,7601,7603,7605,7607,7610,7612,7614,7617,7619,7621],{"class":3057,"line":7587},70,[3055,7589,3123],{"class":3122},[3055,7591,7592],{"class":3126}," cache",[3055,7594,3130],{"class":3069},[3055,7596,3133],{"class":3122},[3055,7598,6766],{"class":3065},[3055,7600,3139],{"class":3069},[3055,7602,3580],{"class":3122},[3055,7604,2971],{"class":3069},[3055,7606,3580],{"class":3122},[3055,7608,7609],{"class":3069},">(",[3055,7611,6885],{"class":3126},[3055,7613,3080],{"class":3069},[3055,7615,7616],{"class":3168},"FromSeconds",[3055,7618,3172],{"class":3069},[3055,7620,3181],{"class":3175},[3055,7622,7623],{"class":3069},"));\n",[3055,7625,7627],{"class":3057,"line":7626},71,[3055,7628,3116],{"emptyLinePlaceholder":3115},[3055,7630,7632],{"class":3057,"line":7631},72,[3055,7633,7634],{"class":3156},"// 100 потоків одночасно працюють з кешем\n",[3055,7636,7638,7640,7642,7644,7646,7648,7650,7652,7654,7656],{"class":3057,"line":7637},73,[3055,7639,3163],{"class":3126},[3055,7641,3080],{"class":3069},[3055,7643,3169],{"class":3168},[3055,7645,3172],{"class":3069},[3055,7647,3176],{"class":3175},[3055,7649,2971],{"class":3069},[3055,7651,4693],{"class":3175},[3055,7653,2971],{"class":3069},[3055,7655,3186],{"class":3126},[3055,7657,3189],{"class":3069},[3055,7659,7661],{"class":3057,"line":7660},74,[3055,7662,3195],{"class":3069},[3055,7664,7666,7668,7670,7672,7674,7676,7678,7680,7682,7684,7686,7688],{"class":3057,"line":7665},75,[3055,7667,5881],{"class":3122},[3055,7669,3673],{"class":3126},[3055,7671,3130],{"class":3069},[3055,7673,3678],{"class":3302},[3055,7675,3307],{"class":3306},[3055,7677,3186],{"class":3126},[3055,7679,5895],{"class":3069},[3055,7681,5898],{"class":3175},[3055,7683,3318],{"class":3306},[3055,7685,3321],{"class":3302},[3055,7687,3465],{"class":3069},[3055,7689,7690],{"class":3156},"// 10 різних ключів\n",[3055,7692,7694],{"class":3057,"line":7693},76,[3055,7695,3116],{"emptyLinePlaceholder":3115},[3055,7697,7699,7701,7703,7705,7708,7710,7712,7714,7716,7718,7720],{"class":3057,"line":7698},77,[3055,7700,5881],{"class":3122},[3055,7702,4912],{"class":3126},[3055,7704,3130],{"class":3069},[3055,7706,7707],{"class":3126},"cache",[3055,7709,3080],{"class":3069},[3055,7711,5066],{"class":3168},[3055,7713,3172],{"class":3069},[3055,7715,3707],{"class":3126},[3055,7717,2971],{"class":3069},[3055,7719,5929],{"class":3126},[3055,7721,3189],{"class":3069},[3055,7723,7725],{"class":3057,"line":7724},78,[3055,7726,3238],{"class":3069},[3055,7728,7730,7732,7734,7736,7738,7741,7743,7745,7747,7750,7752,7754,7756,7758],{"class":3057,"line":7729},79,[3055,7731,5416],{"class":3126},[3055,7733,3080],{"class":3069},[3055,7735,3297],{"class":3168},[3055,7737,3172],{"class":3069},[3055,7739,7740],{"class":3302},"$\"[Thread ",[3055,7742,3307],{"class":3306},[3055,7744,3186],{"class":3126},[3055,7746,3318],{"class":3306},[3055,7748,7749],{"class":3302},"] Computing ",[3055,7751,3307],{"class":3306},[3055,7753,5929],{"class":3126},[3055,7755,3318],{"class":3306},[3055,7757,5202],{"class":3302},[3055,7759,3324],{"class":3069},[3055,7761,7763,7766,7768,7771,7773,7775,7777],{"class":3057,"line":7762},80,[3055,7764,7765],{"class":3126},"        Thread",[3055,7767,3080],{"class":3069},[3055,7769,7770],{"class":3168},"Sleep",[3055,7772,3172],{"class":3069},[3055,7774,4693],{"class":3175},[3055,7776,3266],{"class":3069},[3055,7778,7779],{"class":3156},"// Симуляція дорогої операції\n",[3055,7781,7783,7785,7788,7790,7792,7794,7796],{"class":3057,"line":7782},81,[3055,7784,5441],{"class":3061},[3055,7786,7787],{"class":3302}," $\"value-",[3055,7789,3307],{"class":3306},[3055,7791,5929],{"class":3126},[3055,7793,3318],{"class":3306},[3055,7795,3321],{"class":3302},[3055,7797,3070],{"class":3069},[3055,7799,7801],{"class":3057,"line":7800},82,[3055,7802,3733],{"class":3069},[3055,7804,7806],{"class":3057,"line":7805},83,[3055,7807,3116],{"emptyLinePlaceholder":3115},[3055,7809,7811,7813,7815,7817,7819,7821,7823,7825,7827,7830,7832,7834,7836,7838],{"class":3057,"line":7810},84,[3055,7812,3763],{"class":3126},[3055,7814,3080],{"class":3069},[3055,7816,3297],{"class":3168},[3055,7818,3172],{"class":3069},[3055,7820,7740],{"class":3302},[3055,7822,3307],{"class":3306},[3055,7824,3186],{"class":3126},[3055,7826,3318],{"class":3306},[3055,7828,7829],{"class":3302},"] Got: ",[3055,7831,3307],{"class":3306},[3055,7833,4937],{"class":3126},[3055,7835,3318],{"class":3306},[3055,7837,3321],{"class":3302},[3055,7839,3324],{"class":3069},[3055,7841,7843],{"class":3057,"line":7842},85,[3055,7844,3281],{"class":3069},[3055,7846,7848],{"class":3057,"line":7847},86,[3055,7849,3116],{"emptyLinePlaceholder":3115},[3055,7851,7853],{"class":3057,"line":7852},87,[3055,7854,7855],{"class":3156},"// Тільки 10 обчислень (по одному на ключ), решта взяли з кешу\n",[3032,7857,7859],{"id":7858},"практичний-приклад-thread-safe-word-counter","Практичний Приклад: Thread-Safe Word Counter",[2964,7861,7862,7863,7865],{},"Одне з найпоширеніших застосувань ",[2968,7864,4274],{}," — підрахунок частоти слів у великих текстових файлах. Це класична задача MapReduce, яку можна ефективно розв'язати паралельно.",[2964,7867,7868,7871],{},[2977,7869,7870],{},"Сценарій",": У нас є кілька великих текстових файлів, і ми хочемо підрахувати скільки разів кожне слово зустрічається у всіх файлах разом.",[3044,7873,7876],{"className":3046,"code":7874,"filename":7875,"language":3049,"meta":3050,"style":3051},"using System;\nusing System.Collections.Concurrent;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing System.Diagnostics;\n\npublic class WordCounter\n{\n    private readonly ConcurrentDictionary\u003Cstring, int> _wordCounts = new();\n\n    public void ProcessFile(string filePath)\n    {\n        // Читаємо файл та розбиваємо на слова\n        string content = File.ReadAllText(filePath);\n        var words = content\n            .Split(new[] { ' ', '\\n', '\\r', '\\t', '.', ',', '!', '?' },\n                   StringSplitOptions.RemoveEmptyEntries)\n            .Select(w => w.ToLowerInvariant());\n\n        // Підраховуємо кожне слово\n        foreach (string word in words)\n        {\n            // AddOrUpdate: якщо слова немає → додати 1, якщо є → інкремент\n            _wordCounts.AddOrUpdate(\n                key: word,\n                addValue: 1,                           // Якщо слова немає\n                updateValueFactory: (key, oldValue) => oldValue + 1  // Якщо є\n            );\n        }\n    }\n\n    public void PrintTopWords(int count = 10)\n    {\n        var topWords = _wordCounts\n            .OrderByDescending(kvp => kvp.Value)\n            .Take(count);\n\n        Console.WriteLine($\"\\nTop {count} words:\");\n        foreach (var kvp in topWords)\n        {\n            Console.WriteLine($\"  {kvp.Key}: {kvp.Value}\");\n        }\n    }\n\n    public int TotalWords => _wordCounts.Values.Sum();\n    public int UniqueWords => _wordCounts.Count;\n}\n\n// Використання:\nvar counter = new WordCounter();\nvar files = Directory.GetFiles(@\"C:\\Logs\", \"*.txt\");\n\nConsole.WriteLine($\"Processing {files.Length} files...\");\nvar sw = Stopwatch.StartNew();\n\n// ❌ ПОВІЛЬНО: Послідовна обробка\n// foreach (var file in files)\n// {\n//     counter.ProcessFile(file);\n// }\n\n// ✅ ШВИДКО: Паралельна обробка\nParallel.ForEach(files, file =>\n{\n    counter.ProcessFile(file);\n    Console.WriteLine($\"Processed: {Path.GetFileName(file)}\");\n});\n\nsw.Stop();\nConsole.WriteLine($\"\\nCompleted in {sw.ElapsedMilliseconds}ms\");\nConsole.WriteLine($\"Total words: {counter.TotalWords:N0}\");\nConsole.WriteLine($\"Unique words: {counter.UniqueWords:N0}\");\n\ncounter.PrintTopWords(10);\n","WordCounter.cs",[2968,7877,7878,7886,7902,7915,7928,7944,7957,7961,7970,7974,8001,8005,8023,8027,8032,8056,8068,8138,8150,8174,8178,8183,8201,8205,8210,8221,8233,8248,8272,8277,8281,8285,8289,8311,8315,8327,8348,8362,8366,8394,8410,8414,8454,8458,8462,8466,8491,8510,8514,8518,8522,8538,8567,8571,8600,8619,8623,8628,8633,8638,8643,8648,8652,8657,8677,8681,8697,8731,8735,8739,8751,8784,8818,8850,8854],{"__ignoreMap":3051},[3055,7879,7880,7882,7884],{"class":3057,"line":3058},[3055,7881,3062],{"class":3061},[3055,7883,3066],{"class":3065},[3055,7885,3070],{"class":3069},[3055,7887,7888,7890,7892,7894,7896,7898,7900],{"class":3057,"line":3073},[3055,7889,3062],{"class":3061},[3055,7891,3066],{"class":3065},[3055,7893,3080],{"class":3069},[3055,7895,3083],{"class":3065},[3055,7897,3080],{"class":3069},[3055,7899,6738],{"class":3065},[3055,7901,3070],{"class":3069},[3055,7903,7904,7906,7908,7910,7913],{"class":3057,"line":3093},[3055,7905,3062],{"class":3061},[3055,7907,3066],{"class":3065},[3055,7909,3080],{"class":3069},[3055,7911,7912],{"class":3065},"IO",[3055,7914,3070],{"class":3069},[3055,7916,7917,7919,7921,7923,7926],{"class":3057,"line":3112},[3055,7918,3062],{"class":3061},[3055,7920,3066],{"class":3065},[3055,7922,3080],{"class":3069},[3055,7924,7925],{"class":3065},"Linq",[3055,7927,3070],{"class":3069},[3055,7929,7930,7932,7934,7936,7938,7940,7942],{"class":3057,"line":3119},[3055,7931,3062],{"class":3061},[3055,7933,3066],{"class":3065},[3055,7935,3080],{"class":3069},[3055,7937,3102],{"class":3065},[3055,7939,3080],{"class":3069},[3055,7941,3107],{"class":3065},[3055,7943,3070],{"class":3069},[3055,7945,7946,7948,7950,7952,7955],{"class":3057,"line":3148},[3055,7947,3062],{"class":3061},[3055,7949,3066],{"class":3065},[3055,7951,3080],{"class":3069},[3055,7953,7954],{"class":3065},"Diagnostics",[3055,7956,3070],{"class":3069},[3055,7958,7959],{"class":3057,"line":3153},[3055,7960,3116],{"emptyLinePlaceholder":3115},[3055,7962,7963,7965,7967],{"class":3057,"line":3160},[3055,7964,3367],{"class":3122},[3055,7966,6763],{"class":3122},[3055,7968,7969],{"class":3065}," WordCounter\n",[3055,7971,7972],{"class":3057,"line":3192},[3055,7973,3195],{"class":3069},[3055,7975,7976,7978,7980,7982,7984,7986,7988,7990,7992,7995,7997,7999],{"class":3057,"line":3198},[3055,7977,6799],{"class":3122},[3055,7979,6802],{"class":3122},[3055,7981,4646],{"class":3065},[3055,7983,3139],{"class":3069},[3055,7985,3580],{"class":3122},[3055,7987,2971],{"class":3069},[3055,7989,3142],{"class":3122},[3055,7991,6325],{"class":3069},[3055,7993,7994],{"class":3126},"_wordCounts",[3055,7996,3130],{"class":3069},[3055,7998,3133],{"class":3122},[3055,8000,4071],{"class":3069},[3055,8002,8003],{"class":3057,"line":3235},[3055,8004,3116],{"emptyLinePlaceholder":3115},[3055,8006,8007,8009,8011,8014,8016,8018,8021],{"class":3057,"line":3241},[3055,8008,6878],{"class":3122},[3055,8010,3370],{"class":3122},[3055,8012,8013],{"class":3168}," ProcessFile",[3055,8015,3172],{"class":3069},[3055,8017,3580],{"class":3122},[3055,8019,8020],{"class":3126}," filePath",[3055,8022,3384],{"class":3069},[3055,8024,8025],{"class":3057,"line":3272},[3055,8026,3238],{"class":3069},[3055,8028,8029],{"class":3057,"line":3278},[3055,8030,8031],{"class":3156},"        // Читаємо файл та розбиваємо на слова\n",[3055,8033,8034,8036,8039,8041,8044,8046,8049,8051,8054],{"class":3057,"line":3284},[3055,8035,4143],{"class":3122},[3055,8037,8038],{"class":3126}," content",[3055,8040,3130],{"class":3069},[3055,8042,8043],{"class":3126},"File",[3055,8045,3080],{"class":3069},[3055,8047,8048],{"class":3168},"ReadAllText",[3055,8050,3172],{"class":3069},[3055,8052,8053],{"class":3126},"filePath",[3055,8055,3324],{"class":3069},[3055,8057,8058,8060,8063,8065],{"class":3057,"line":3289},[3055,8059,7160],{"class":3122},[3055,8061,8062],{"class":3126}," words",[3055,8064,3130],{"class":3069},[3055,8066,8067],{"class":3126},"content\n",[3055,8069,8070,8073,8076,8078,8080,8083,8086,8088,8091,8095,8097,8099,8101,8104,8106,8108,8110,8113,8115,8117,8120,8122,8125,8127,8130,8132,8135],{"class":3057,"line":3327},[3055,8071,8072],{"class":3069},"            .",[3055,8074,8075],{"class":3168},"Split",[3055,8077,3172],{"class":3069},[3055,8079,3133],{"class":3122},[3055,8081,8082],{"class":3069},"[] { ",[3055,8084,8085],{"class":3302},"' '",[3055,8087,2971],{"class":3069},[3055,8089,8090],{"class":3302},"'",[3055,8092,8094],{"class":8093},"sjcCO","\\n",[3055,8096,8090],{"class":3302},[3055,8098,2971],{"class":3069},[3055,8100,8090],{"class":3302},[3055,8102,8103],{"class":8093},"\\r",[3055,8105,8090],{"class":3302},[3055,8107,2971],{"class":3069},[3055,8109,8090],{"class":3302},[3055,8111,8112],{"class":8093},"\\t",[3055,8114,8090],{"class":3302},[3055,8116,2971],{"class":3069},[3055,8118,8119],{"class":3302},"'.'",[3055,8121,2971],{"class":3069},[3055,8123,8124],{"class":3302},"','",[3055,8126,2971],{"class":3069},[3055,8128,8129],{"class":3302},"'!'",[3055,8131,2971],{"class":3069},[3055,8133,8134],{"class":3302},"'?'",[3055,8136,8137],{"class":3069}," },\n",[3055,8139,8140,8143,8145,8148],{"class":3057,"line":3333},[3055,8141,8142],{"class":3126},"                   StringSplitOptions",[3055,8144,3080],{"class":3069},[3055,8146,8147],{"class":3126},"RemoveEmptyEntries",[3055,8149,3384],{"class":3069},[3055,8151,8152,8154,8157,8159,8162,8164,8166,8168,8171],{"class":3057,"line":3338},[3055,8153,8072],{"class":3069},[3055,8155,8156],{"class":3168},"Select",[3055,8158,3172],{"class":3069},[3055,8160,8161],{"class":3126},"w",[3055,8163,7560],{"class":3069},[3055,8165,8161],{"class":3126},[3055,8167,3080],{"class":3069},[3055,8169,8170],{"class":3168},"ToLowerInvariant",[3055,8172,8173],{"class":3069},"());\n",[3055,8175,8176],{"class":3057,"line":3755},[3055,8177,3116],{"emptyLinePlaceholder":3115},[3055,8179,8180],{"class":3057,"line":3760},[3055,8181,8182],{"class":3156},"        // Підраховуємо кожне слово\n",[3055,8184,8185,8188,8190,8192,8195,8197,8199],{"class":3057,"line":3797},[3055,8186,8187],{"class":3061},"        foreach",[3055,8189,3204],{"class":3069},[3055,8191,3580],{"class":3122},[3055,8193,8194],{"class":3126}," word",[3055,8196,5967],{"class":3061},[3055,8198,8062],{"class":3126},[3055,8200,3384],{"class":3069},[3055,8202,8203],{"class":3057,"line":3826},[3055,8204,3665],{"class":3069},[3055,8206,8207],{"class":3057,"line":3831},[3055,8208,8209],{"class":3156},"            // AddOrUpdate: якщо слова немає → додати 1, якщо є → інкремент\n",[3055,8211,8212,8215,8217,8219],{"class":3057,"line":3836},[3055,8213,8214],{"class":3126},"            _wordCounts",[3055,8216,3080],{"class":3069},[3055,8218,5545],{"class":3168},[3055,8220,5548],{"class":3069},[3055,8222,8223,8226,8228,8231],{"class":3057,"line":3842},[3055,8224,8225],{"class":3126},"                key",[3055,8227,5292],{"class":3069},[3055,8229,8230],{"class":3126},"word",[3055,8232,5254],{"class":3069},[3055,8234,8235,8238,8240,8242,8245],{"class":3057,"line":3848},[3055,8236,8237],{"class":3126},"                addValue",[3055,8239,5292],{"class":3069},[3055,8241,3433],{"class":3175},[3055,8243,8244],{"class":3069},",                           ",[3055,8246,8247],{"class":3156},"// Якщо слова немає\n",[3055,8249,8250,8253,8255,8257,8259,8261,8263,8265,8267,8269],{"class":3057,"line":3854},[3055,8251,8252],{"class":3126},"                updateValueFactory",[3055,8254,5583],{"class":3069},[3055,8256,3707],{"class":3126},[3055,8258,2971],{"class":3069},[3055,8260,5590],{"class":3126},[3055,8262,5271],{"class":3069},[3055,8264,5590],{"class":3126},[3055,8266,3261],{"class":3069},[3055,8268,3433],{"class":3175},[3055,8270,8271],{"class":3156},"  // Якщо є\n",[3055,8273,8274],{"class":3057,"line":4603},[3055,8275,8276],{"class":3069},"            );\n",[3055,8278,8279],{"class":3057,"line":4609},[3055,8280,3728],{"class":3069},[3055,8282,8283],{"class":3057,"line":7082},[3055,8284,3275],{"class":3069},[3055,8286,8287],{"class":3057,"line":7095},[3055,8288,3116],{"emptyLinePlaceholder":3115},[3055,8290,8291,8293,8295,8298,8300,8302,8305,8307,8309],{"class":3057,"line":7104},[3055,8292,6878],{"class":3122},[3055,8294,3370],{"class":3122},[3055,8296,8297],{"class":3168}," PrintTopWords",[3055,8299,3172],{"class":3069},[3055,8301,3142],{"class":3122},[3055,8303,8304],{"class":3126}," count",[3055,8306,3130],{"class":3069},[3055,8308,3181],{"class":3175},[3055,8310,3384],{"class":3069},[3055,8312,8313],{"class":3057,"line":7109},[3055,8314,3238],{"class":3069},[3055,8316,8317,8319,8322,8324],{"class":3057,"line":7114},[3055,8318,7160],{"class":3122},[3055,8320,8321],{"class":3126}," topWords",[3055,8323,3130],{"class":3069},[3055,8325,8326],{"class":3126},"_wordCounts\n",[3055,8328,8329,8331,8334,8336,8338,8340,8342,8344,8346],{"class":3057,"line":7152},[3055,8330,8072],{"class":3069},[3055,8332,8333],{"class":3168},"OrderByDescending",[3055,8335,3172],{"class":3069},[3055,8337,5993],{"class":3126},[3055,8339,7560],{"class":3069},[3055,8341,5993],{"class":3126},[3055,8343,3080],{"class":3069},[3055,8345,6011],{"class":3126},[3055,8347,3384],{"class":3069},[3055,8349,8350,8352,8355,8357,8360],{"class":3057,"line":7157},[3055,8351,8072],{"class":3069},[3055,8353,8354],{"class":3168},"Take",[3055,8356,3172],{"class":3069},[3055,8358,8359],{"class":3126},"count",[3055,8361,3324],{"class":3069},[3055,8363,8364],{"class":3057,"line":7187},[3055,8365,3116],{"emptyLinePlaceholder":3115},[3055,8367,8368,8370,8372,8374,8376,8378,8380,8383,8385,8387,8389,8392],{"class":3057,"line":7211},[3055,8369,5416],{"class":3126},[3055,8371,3080],{"class":3069},[3055,8373,3297],{"class":3168},[3055,8375,3172],{"class":3069},[3055,8377,5988],{"class":3302},[3055,8379,8094],{"class":8093},[3055,8381,8382],{"class":3302},"Top ",[3055,8384,3307],{"class":3306},[3055,8386,8359],{"class":3126},[3055,8388,3318],{"class":3306},[3055,8390,8391],{"class":3302}," words:\"",[3055,8393,3324],{"class":3069},[3055,8395,8396,8398,8400,8402,8404,8406,8408],{"class":3057,"line":7216},[3055,8397,8187],{"class":3061},[3055,8399,3204],{"class":3069},[3055,8401,3123],{"class":3122},[3055,8403,5964],{"class":3126},[3055,8405,5967],{"class":3061},[3055,8407,8321],{"class":3126},[3055,8409,3384],{"class":3069},[3055,8411,8412],{"class":3057,"line":7235},[3055,8413,3665],{"class":3069},[3055,8415,8416,8419,8421,8423,8425,8428,8430,8432,8434,8436,8438,8440,8442,8444,8446,8448,8450,8452],{"class":3057,"line":7240},[3055,8417,8418],{"class":3126},"            Console",[3055,8420,3080],{"class":3069},[3055,8422,3297],{"class":3168},[3055,8424,3172],{"class":3069},[3055,8426,8427],{"class":3302},"$\"  ",[3055,8429,3307],{"class":3306},[3055,8431,5993],{"class":3126},[3055,8433,3080],{"class":3306},[3055,8435,5998],{"class":3126},[3055,8437,3318],{"class":3306},[3055,8439,5292],{"class":3302},[3055,8441,3307],{"class":3306},[3055,8443,5993],{"class":3126},[3055,8445,3080],{"class":3306},[3055,8447,6011],{"class":3126},[3055,8449,3318],{"class":3306},[3055,8451,3321],{"class":3302},[3055,8453,3324],{"class":3069},[3055,8455,8456],{"class":3057,"line":7245},[3055,8457,3728],{"class":3069},[3055,8459,8460],{"class":3057,"line":7293},[3055,8461,3275],{"class":3069},[3055,8463,8464],{"class":3057,"line":7298},[3055,8465,3116],{"emptyLinePlaceholder":3115},[3055,8467,8468,8470,8472,8475,8477,8479,8481,8484,8486,8489],{"class":3057,"line":7323},[3055,8469,6878],{"class":3122},[3055,8471,4909],{"class":3122},[3055,8473,8474],{"class":3126}," TotalWords",[3055,8476,7560],{"class":3069},[3055,8478,7994],{"class":3126},[3055,8480,3080],{"class":3069},[3055,8482,8483],{"class":3126},"Values",[3055,8485,3080],{"class":3069},[3055,8487,8488],{"class":3168},"Sum",[3055,8490,4071],{"class":3069},[3055,8492,8493,8495,8497,8500,8502,8504,8506,8508],{"class":3057,"line":7328},[3055,8494,6878],{"class":3122},[3055,8496,4909],{"class":3122},[3055,8498,8499],{"class":3126}," UniqueWords",[3055,8501,7560],{"class":3069},[3055,8503,7994],{"class":3126},[3055,8505,3080],{"class":3069},[3055,8507,3315],{"class":3126},[3055,8509,3070],{"class":3069},[3055,8511,8512],{"class":3057,"line":7353},[3055,8513,3484],{"class":3069},[3055,8515,8516],{"class":3057,"line":7358},[3055,8517,3116],{"emptyLinePlaceholder":3115},[3055,8519,8520],{"class":3057,"line":7376},[3055,8521,7584],{"class":3156},[3055,8523,8524,8526,8529,8531,8533,8536],{"class":3057,"line":7396},[3055,8525,3123],{"class":3122},[3055,8527,8528],{"class":3126}," counter",[3055,8530,3130],{"class":3069},[3055,8532,3133],{"class":3122},[3055,8534,8535],{"class":3065}," WordCounter",[3055,8537,4071],{"class":3069},[3055,8539,8540,8542,8545,8547,8550,8552,8555,8557,8560,8562,8565],{"class":3057,"line":7402},[3055,8541,3123],{"class":3122},[3055,8543,8544],{"class":3126}," files",[3055,8546,3130],{"class":3069},[3055,8548,8549],{"class":3126},"Directory",[3055,8551,3080],{"class":3069},[3055,8553,8554],{"class":3168},"GetFiles",[3055,8556,3172],{"class":3069},[3055,8558,8559],{"class":3302},"@\"C:\\Logs\"",[3055,8561,2971],{"class":3069},[3055,8563,8564],{"class":3302},"\"*.txt\"",[3055,8566,3324],{"class":3069},[3055,8568,8569],{"class":3057,"line":7407},[3055,8570,3116],{"emptyLinePlaceholder":3115},[3055,8572,8573,8575,8577,8579,8581,8584,8586,8589,8591,8593,8595,8598],{"class":3057,"line":7413},[3055,8574,3292],{"class":3126},[3055,8576,3080],{"class":3069},[3055,8578,3297],{"class":3168},[3055,8580,3172],{"class":3069},[3055,8582,8583],{"class":3302},"$\"Processing ",[3055,8585,3307],{"class":3306},[3055,8587,8588],{"class":3126},"files",[3055,8590,3080],{"class":3306},[3055,8592,3409],{"class":3126},[3055,8594,3318],{"class":3306},[3055,8596,8597],{"class":3302}," files...\"",[3055,8599,3324],{"class":3069},[3055,8601,8602,8604,8607,8609,8612,8614,8617],{"class":3057,"line":7437},[3055,8603,3123],{"class":3122},[3055,8605,8606],{"class":3126}," sw",[3055,8608,3130],{"class":3069},[3055,8610,8611],{"class":3126},"Stopwatch",[3055,8613,3080],{"class":3069},[3055,8615,8616],{"class":3168},"StartNew",[3055,8618,4071],{"class":3069},[3055,8620,8621],{"class":3057,"line":7442},[3055,8622,3116],{"emptyLinePlaceholder":3115},[3055,8624,8625],{"class":3057,"line":7448},[3055,8626,8627],{"class":3156},"// ❌ ПОВІЛЬНО: Послідовна обробка\n",[3055,8629,8630],{"class":3057,"line":7469},[3055,8631,8632],{"class":3156},"// foreach (var file in files)\n",[3055,8634,8635],{"class":3057,"line":7490},[3055,8636,8637],{"class":3156},"// {\n",[3055,8639,8640],{"class":3057,"line":7495},[3055,8641,8642],{"class":3156},"//     counter.ProcessFile(file);\n",[3055,8644,8645],{"class":3057,"line":7500},[3055,8646,8647],{"class":3156},"// }\n",[3055,8649,8650],{"class":3057,"line":7513},[3055,8651,3116],{"emptyLinePlaceholder":3115},[3055,8653,8654],{"class":3057,"line":7518},[3055,8655,8656],{"class":3156},"// ✅ ШВИДКО: Паралельна обробка\n",[3055,8658,8659,8661,8663,8666,8668,8670,8672,8675],{"class":3057,"line":7523},[3055,8660,3163],{"class":3126},[3055,8662,3080],{"class":3069},[3055,8664,8665],{"class":3168},"ForEach",[3055,8667,3172],{"class":3069},[3055,8669,8588],{"class":3126},[3055,8671,2971],{"class":3069},[3055,8673,8674],{"class":3126},"file",[3055,8676,3189],{"class":3069},[3055,8678,8679],{"class":3057,"line":7545},[3055,8680,3195],{"class":3069},[3055,8682,8683,8686,8688,8691,8693,8695],{"class":3057,"line":7550},[3055,8684,8685],{"class":3126},"    counter",[3055,8687,3080],{"class":3069},[3055,8689,8690],{"class":3168},"ProcessFile",[3055,8692,3172],{"class":3069},[3055,8694,8674],{"class":3126},[3055,8696,3324],{"class":3069},[3055,8698,8699,8701,8703,8705,8707,8710,8712,8715,8717,8720,8722,8724,8727,8729],{"class":3057,"line":7571},[3055,8700,3763],{"class":3126},[3055,8702,3080],{"class":3069},[3055,8704,3297],{"class":3168},[3055,8706,3172],{"class":3069},[3055,8708,8709],{"class":3302},"$\"Processed: ",[3055,8711,3307],{"class":3306},[3055,8713,8714],{"class":3126},"Path",[3055,8716,3080],{"class":3306},[3055,8718,8719],{"class":3168},"GetFileName",[3055,8721,3172],{"class":3306},[3055,8723,8674],{"class":3126},[3055,8725,8726],{"class":3306},")}",[3055,8728,3321],{"class":3302},[3055,8730,3324],{"class":3069},[3055,8732,8733],{"class":3057,"line":7576},[3055,8734,3281],{"class":3069},[3055,8736,8737],{"class":3057,"line":7581},[3055,8738,3116],{"emptyLinePlaceholder":3115},[3055,8740,8741,8744,8746,8749],{"class":3057,"line":7587},[3055,8742,8743],{"class":3126},"sw",[3055,8745,3080],{"class":3069},[3055,8747,8748],{"class":3168},"Stop",[3055,8750,4071],{"class":3069},[3055,8752,8753,8755,8757,8759,8761,8763,8765,8768,8770,8772,8774,8777,8779,8782],{"class":3057,"line":7626},[3055,8754,3292],{"class":3126},[3055,8756,3080],{"class":3069},[3055,8758,3297],{"class":3168},[3055,8760,3172],{"class":3069},[3055,8762,5988],{"class":3302},[3055,8764,8094],{"class":8093},[3055,8766,8767],{"class":3302},"Completed in ",[3055,8769,3307],{"class":3306},[3055,8771,8743],{"class":3126},[3055,8773,3080],{"class":3306},[3055,8775,8776],{"class":3126},"ElapsedMilliseconds",[3055,8778,3318],{"class":3306},[3055,8780,8781],{"class":3302},"ms\"",[3055,8783,3324],{"class":3069},[3055,8785,8786,8788,8790,8792,8794,8797,8799,8802,8804,8807,8809,8812,8814,8816],{"class":3057,"line":7631},[3055,8787,3292],{"class":3126},[3055,8789,3080],{"class":3069},[3055,8791,3297],{"class":3168},[3055,8793,3172],{"class":3069},[3055,8795,8796],{"class":3302},"$\"Total words: ",[3055,8798,3307],{"class":3306},[3055,8800,8801],{"class":3126},"counter",[3055,8803,3080],{"class":3306},[3055,8805,8806],{"class":3126},"TotalWords",[3055,8808,3490],{"class":3069},[3055,8810,8811],{"class":3126},"N0",[3055,8813,3318],{"class":3306},[3055,8815,3321],{"class":3302},[3055,8817,3324],{"class":3069},[3055,8819,8820,8822,8824,8826,8828,8831,8833,8835,8837,8840,8842,8844,8846,8848],{"class":3057,"line":7637},[3055,8821,3292],{"class":3126},[3055,8823,3080],{"class":3069},[3055,8825,3297],{"class":3168},[3055,8827,3172],{"class":3069},[3055,8829,8830],{"class":3302},"$\"Unique words: ",[3055,8832,3307],{"class":3306},[3055,8834,8801],{"class":3126},[3055,8836,3080],{"class":3306},[3055,8838,8839],{"class":3126},"UniqueWords",[3055,8841,3490],{"class":3069},[3055,8843,8811],{"class":3126},[3055,8845,3318],{"class":3306},[3055,8847,3321],{"class":3302},[3055,8849,3324],{"class":3069},[3055,8851,8852],{"class":3057,"line":7660},[3055,8853,3116],{"emptyLinePlaceholder":3115},[3055,8855,8856,8858,8860,8863,8865,8867],{"class":3057,"line":7665},[3055,8857,8801],{"class":3126},[3055,8859,3080],{"class":3069},[3055,8861,8862],{"class":3168},"PrintTopWords",[3055,8864,3172],{"class":3069},[3055,8866,3181],{"class":3175},[3055,8868,3324],{"class":3069},[2964,8870,8871,3490],{},[2977,8872,8873],{},"Вивід (приклад)",[3044,8875,8878],{"className":8876,"code":8877,"language":3496},[3494],"Processing 50 files...\nProcessed: log1.txt\nProcessed: log3.txt\nProcessed: log2.txt\n...\nCompleted in 1,234ms\nTotal words: 1,245,678\nUnique words: 45,123\n\nTop 10 words:\n  the: 89,234\n  and: 67,890\n  error: 45,123\n  to: 34,567\n  in: 29,876\n  a: 28,345\n  is: 23,456\n  of: 21,234\n  for: 19,876\n  with: 18,765\n",[2968,8879,8877],{"__ignoreMap":3051},[2964,8881,8882],{},[2977,8883,8884],{},"Чому це працює ефективно?",[3877,8886,8887,8896,8902],{},[3012,8888,8889,5292,8892,8895],{},[2977,8890,8891],{},"Паралельна обробка файлів",[2968,8893,8894],{},"Parallel.ForEach"," розподіляє файли між потоками",[3012,8897,8898,8901],{},[2977,8899,8900],{},"Striped locking",": Різні слова (з різними hash codes) можуть оновлюватись паралельно",[3012,8903,8904,8906],{},[2977,8905,5545],{},": Атомарна операція — не потрібен додатковий lock",[2964,8908,8909,8912],{},[2977,8910,8911],{},"Альтернативний підхід з GetOrAdd"," (менш ефективний):",[3044,8914,8916],{"className":3046,"code":8915,"language":3049,"meta":3051,"style":3051},"// ❌ Менш ефективно: два звернення до словника\nforeach (string word in words)\n{\n    int currentCount = _wordCounts.GetOrAdd(word, 0);\n    _wordCounts[word] = currentCount + 1;  // Race condition!\n}\n",[2968,8917,8918,8923,8939,8943,8969,8992],{"__ignoreMap":3051},[3055,8919,8920],{"class":3057,"line":3058},[3055,8921,8922],{"class":3156},"// ❌ Менш ефективно: два звернення до словника\n",[3055,8924,8925,8927,8929,8931,8933,8935,8937],{"class":3057,"line":3073},[3055,8926,5957],{"class":3061},[3055,8928,3204],{"class":3069},[3055,8930,3580],{"class":3122},[3055,8932,8194],{"class":3126},[3055,8934,5967],{"class":3061},[3055,8936,8062],{"class":3126},[3055,8938,3384],{"class":3069},[3055,8940,8941],{"class":3057,"line":3093},[3055,8942,3195],{"class":3069},[3055,8944,8945,8948,8951,8953,8955,8957,8959,8961,8963,8965,8967],{"class":3057,"line":3112},[3055,8946,8947],{"class":3122},"    int",[3055,8949,8950],{"class":3126}," currentCount",[3055,8952,3130],{"class":3069},[3055,8954,7994],{"class":3126},[3055,8956,3080],{"class":3069},[3055,8958,5066],{"class":3168},[3055,8960,3172],{"class":3069},[3055,8962,8230],{"class":3126},[3055,8964,2971],{"class":3069},[3055,8966,3176],{"class":3175},[3055,8968,3324],{"class":3069},[3055,8970,8971,8974,8976,8978,8980,8983,8985,8987,8989],{"class":3057,"line":3119},[3055,8972,8973],{"class":3126},"    _wordCounts",[3055,8975,3454],{"class":3069},[3055,8977,8230],{"class":3126},[3055,8979,3459],{"class":3069},[3055,8981,8982],{"class":3126},"currentCount",[3055,8984,3261],{"class":3069},[3055,8986,3433],{"class":3175},[3055,8988,3465],{"class":3069},[3055,8990,8991],{"class":3156},"// Race condition!\n",[3055,8993,8994],{"class":3057,"line":3148},[3055,8995,3484],{"class":3069},[2964,8997,8998,9001,9002,9004,9005,9007],{},[2977,8999,9000],{},"Проблема",": Між ",[2968,9003,5066],{}," та присвоєнням інший потік може змінити значення, і ми втратимо оновлення. ",[2968,9006,5545],{}," робить це атомарно.",[2964,9009,9010,3490],{},[2977,9011,9012],{},"Benchmark: ConcurrentDictionary vs Dictionary + lock",[3044,9014,9016],{"className":3046,"code":9015,"language":3049,"meta":3051,"style":3051},"// Benchmark: 50 файлів, ~1MB кожен, 10 потоків\nDictionary + lock:        ~3,500ms\nConcurrentDictionary:     ~1,200ms  (в 3x швидше!)\n",[2968,9017,9018,9023,9035],{"__ignoreMap":3051},[3055,9019,9020],{"class":3057,"line":3058},[3055,9021,9022],{"class":3156},"// Benchmark: 50 файлів, ~1MB кожен, 10 потоків\n",[3055,9024,9025,9028,9030,9032],{"class":3057,"line":3073},[3055,9026,9027],{"class":3126},"Dictionary",[3055,9029,3261],{"class":3069},[3055,9031,2970],{"class":3061},[3055,9033,9034],{"class":3069},":        ~3,500ms\n",[3055,9036,9037,9040,9043,9047,9050],{"class":3057,"line":3093},[3055,9038,9039],{"class":3069},"ConcurrentDictionary:     ~1,200ms  (",[3055,9041,9042],{"class":3126},"в",[3055,9044,9046],{"class":9045},"se1LK"," 3x",[3055,9048,9049],{"class":3126}," швидше",[3055,9051,9052],{"class":3069},"!)\n",[3025,9054],{},[2959,9056,9058,9059],{"id":9057},"concurrentqueue-lock-free-fifo","ConcurrentQueue",[3037,9060,9061],{}," — Lock-Free FIFO",[3032,9063,9065],{"id":9064},"архітектура-lock-free-linked-list","Архітектура: Lock-Free Linked List",[2964,9067,9068,9071,9072,3871,9075,3490],{},[2968,9069,9070],{},"ConcurrentQueue\u003CT>"," реалізована як ",[2977,9073,9074],{},"lock-free linked list",[2977,9076,9077],{},"окремими head та tail вказівниками",[3044,9079,9082],{"className":9080,"code":9081,"language":3496},[3494],"┌──────┐    ┌──────┐    ┌──────┐    ┌──────┐\n│ Node │───▶│ Node │───▶│ Node │───▶│ Node │───▶ null\n│  A   │    │  B   │    │  C   │    │  D   │\n└──────┘    └──────┘    └──────┘    └──────┘\n   ↑                                    ↑\n  head                                 tail\n(Dequeue тут)                    (Enqueue тут)\n",[2968,9083,9081],{"__ignoreMap":3051},[2964,9085,9086,3490],{},[2977,9087,9088],{},"Ключові особливості",[3009,9090,9091,9101,9111,9121],{},[3012,9092,9093,9096,9097,9100],{},[2968,9094,9095],{},"Enqueue"," додає у ",[2977,9098,9099],{},"tail"," (кінець)",[3012,9102,9103,9106,9107,9110],{},[2968,9104,9105],{},"TryDequeue"," забирає з ",[2977,9108,9109],{},"head"," (початок)",[3012,9112,9113,9114,9117,9118],{},"Обидві операції ",[2977,9115,9116],{},"lock-free"," через ",[2968,9119,9120],{},"Interlocked.CompareExchange",[3012,9122,9123],{},"Немає блокування потоків → висока scalability",[3032,9125,4622],{"id":9126},"основні-методи-1",[3044,9128,9131],{"className":3046,"code":9129,"filename":9130,"language":3049,"meta":3050,"style":3051},"using System.Collections.Concurrent;\n\nvar queue = new ConcurrentQueue\u003Cint>();\n\n// Enqueue — додати елемент (завжди успішно)\nqueue.Enqueue(1);\nqueue.Enqueue(2);\nqueue.Enqueue(3);\n\n// TryDequeue — забрати елемент\nif (queue.TryDequeue(out int result))\n{\n    Console.WriteLine($\"Dequeued: {result}\");  // 1 (FIFO)\n}\n\n// TryPeek — подивитись без видалення\nif (queue.TryPeek(out int peeked))\n{\n    Console.WriteLine($\"Peeked: {peeked}\");  // 2\n}\n\n// Count — приблизна кількість (snapshot)\nConsole.WriteLine($\"Count: {queue.Count}\");  // ~2\n\n// IsEmpty — перевірка чи порожня\nConsole.WriteLine($\"IsEmpty: {queue.IsEmpty}\");  // false\n","ConcurrentQueueBasics.cs",[2968,9132,9133,9149,9153,9173,9177,9182,9197,9211,9226,9230,9235,9258,9262,9289,9293,9297,9302,9326,9330,9357,9361,9365,9370,9400,9404,9409],{"__ignoreMap":3051},[3055,9134,9135,9137,9139,9141,9143,9145,9147],{"class":3057,"line":3058},[3055,9136,3062],{"class":3061},[3055,9138,3066],{"class":3065},[3055,9140,3080],{"class":3069},[3055,9142,3083],{"class":3065},[3055,9144,3080],{"class":3069},[3055,9146,6738],{"class":3065},[3055,9148,3070],{"class":3069},[3055,9150,9151],{"class":3057,"line":3073},[3055,9152,3116],{"emptyLinePlaceholder":3115},[3055,9154,9155,9157,9160,9162,9164,9167,9169,9171],{"class":3057,"line":3093},[3055,9156,3123],{"class":3122},[3055,9158,9159],{"class":3126}," queue",[3055,9161,3130],{"class":3069},[3055,9163,3133],{"class":3122},[3055,9165,9166],{"class":3065}," ConcurrentQueue",[3055,9168,3139],{"class":3069},[3055,9170,3142],{"class":3122},[3055,9172,3145],{"class":3069},[3055,9174,9175],{"class":3057,"line":3112},[3055,9176,3116],{"emptyLinePlaceholder":3115},[3055,9178,9179],{"class":3057,"line":3119},[3055,9180,9181],{"class":3156},"// Enqueue — додати елемент (завжди успішно)\n",[3055,9183,9184,9187,9189,9191,9193,9195],{"class":3057,"line":3148},[3055,9185,9186],{"class":3126},"queue",[3055,9188,3080],{"class":3069},[3055,9190,9095],{"class":3168},[3055,9192,3172],{"class":3069},[3055,9194,3433],{"class":3175},[3055,9196,3324],{"class":3069},[3055,9198,9199,9201,9203,9205,9207,9209],{"class":3057,"line":3153},[3055,9200,9186],{"class":3126},[3055,9202,3080],{"class":3069},[3055,9204,9095],{"class":3168},[3055,9206,3172],{"class":3069},[3055,9208,5278],{"class":3175},[3055,9210,3324],{"class":3069},[3055,9212,9213,9215,9217,9219,9221,9224],{"class":3057,"line":3160},[3055,9214,9186],{"class":3126},[3055,9216,3080],{"class":3069},[3055,9218,9095],{"class":3168},[3055,9220,3172],{"class":3069},[3055,9222,9223],{"class":3175},"3",[3055,9225,3324],{"class":3069},[3055,9227,9228],{"class":3057,"line":3192},[3055,9229,3116],{"emptyLinePlaceholder":3115},[3055,9231,9232],{"class":3057,"line":3198},[3055,9233,9234],{"class":3156},"// TryDequeue — забрати елемент\n",[3055,9236,9237,9239,9241,9243,9245,9247,9249,9251,9253,9256],{"class":3057,"line":3235},[3055,9238,4888],{"class":3061},[3055,9240,3204],{"class":3069},[3055,9242,9186],{"class":3126},[3055,9244,3080],{"class":3069},[3055,9246,9105],{"class":3168},[3055,9248,3172],{"class":3069},[3055,9250,4906],{"class":3122},[3055,9252,4909],{"class":3122},[3055,9254,9255],{"class":3126}," result",[3055,9257,4915],{"class":3069},[3055,9259,9260],{"class":3057,"line":3241},[3055,9261,3195],{"class":3069},[3055,9263,9264,9266,9268,9270,9272,9275,9277,9280,9282,9284,9286],{"class":3057,"line":3272},[3055,9265,3763],{"class":3126},[3055,9267,3080],{"class":3069},[3055,9269,3297],{"class":3168},[3055,9271,3172],{"class":3069},[3055,9273,9274],{"class":3302},"$\"Dequeued: ",[3055,9276,3307],{"class":3306},[3055,9278,9279],{"class":3126},"result",[3055,9281,3318],{"class":3306},[3055,9283,3321],{"class":3302},[3055,9285,3266],{"class":3069},[3055,9287,9288],{"class":3156},"// 1 (FIFO)\n",[3055,9290,9291],{"class":3057,"line":3278},[3055,9292,3484],{"class":3069},[3055,9294,9295],{"class":3057,"line":3284},[3055,9296,3116],{"emptyLinePlaceholder":3115},[3055,9298,9299],{"class":3057,"line":3289},[3055,9300,9301],{"class":3156},"// TryPeek — подивитись без видалення\n",[3055,9303,9304,9306,9308,9310,9312,9315,9317,9319,9321,9324],{"class":3057,"line":3327},[3055,9305,4888],{"class":3061},[3055,9307,3204],{"class":3069},[3055,9309,9186],{"class":3126},[3055,9311,3080],{"class":3069},[3055,9313,9314],{"class":3168},"TryPeek",[3055,9316,3172],{"class":3069},[3055,9318,4906],{"class":3122},[3055,9320,4909],{"class":3122},[3055,9322,9323],{"class":3126}," peeked",[3055,9325,4915],{"class":3069},[3055,9327,9328],{"class":3057,"line":3333},[3055,9329,3195],{"class":3069},[3055,9331,9332,9334,9336,9338,9340,9343,9345,9348,9350,9352,9354],{"class":3057,"line":3338},[3055,9333,3763],{"class":3126},[3055,9335,3080],{"class":3069},[3055,9337,3297],{"class":3168},[3055,9339,3172],{"class":3069},[3055,9341,9342],{"class":3302},"$\"Peeked: ",[3055,9344,3307],{"class":3306},[3055,9346,9347],{"class":3126},"peeked",[3055,9349,3318],{"class":3306},[3055,9351,3321],{"class":3302},[3055,9353,3266],{"class":3069},[3055,9355,9356],{"class":3156},"// 2\n",[3055,9358,9359],{"class":3057,"line":3755},[3055,9360,3484],{"class":3069},[3055,9362,9363],{"class":3057,"line":3760},[3055,9364,3116],{"emptyLinePlaceholder":3115},[3055,9366,9367],{"class":3057,"line":3797},[3055,9368,9369],{"class":3156},"// Count — приблизна кількість (snapshot)\n",[3055,9371,9372,9374,9376,9378,9380,9383,9385,9387,9389,9391,9393,9395,9397],{"class":3057,"line":3826},[3055,9373,3292],{"class":3126},[3055,9375,3080],{"class":3069},[3055,9377,3297],{"class":3168},[3055,9379,3172],{"class":3069},[3055,9381,9382],{"class":3302},"$\"Count: ",[3055,9384,3307],{"class":3306},[3055,9386,9186],{"class":3126},[3055,9388,3080],{"class":3306},[3055,9390,3315],{"class":3126},[3055,9392,3318],{"class":3306},[3055,9394,3321],{"class":3302},[3055,9396,3266],{"class":3069},[3055,9398,9399],{"class":3156},"// ~2\n",[3055,9401,9402],{"class":3057,"line":3831},[3055,9403,3116],{"emptyLinePlaceholder":3115},[3055,9405,9406],{"class":3057,"line":3836},[3055,9407,9408],{"class":3156},"// IsEmpty — перевірка чи порожня\n",[3055,9410,9411,9413,9415,9417,9419,9422,9424,9426,9428,9431,9433,9435,9437],{"class":3057,"line":3842},[3055,9412,3292],{"class":3126},[3055,9414,3080],{"class":3069},[3055,9416,3297],{"class":3168},[3055,9418,3172],{"class":3069},[3055,9420,9421],{"class":3302},"$\"IsEmpty: ",[3055,9423,3307],{"class":3306},[3055,9425,9186],{"class":3126},[3055,9427,3080],{"class":3306},[3055,9429,9430],{"class":3126},"IsEmpty",[3055,9432,3318],{"class":3306},[3055,9434,3321],{"class":3302},[3055,9436,3266],{"class":3069},[3055,9438,4779],{"class":3156},[2964,9440,9441,5292,9443,9445,9446,9448,9449,9452,9453,9445,9455,9457],{},[2977,9442,5320],{},[2968,9444,3315],{}," та ",[2968,9447,9430],{}," — це ",[2977,9450,9451],{},"snapshot"," значення. Між викликом ",[2968,9454,9430],{},[2968,9456,9105],{}," інший потік може змінити чергу.",[3032,9459,9461],{"id":9460},"практичний-приклад-producer-consumer","Практичний Приклад: Producer-Consumer",[3044,9463,9466],{"className":3046,"code":9464,"filename":9465,"language":3049,"meta":3050,"style":3051},"using System;\nusing System.Collections.Concurrent;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nvar queue = new ConcurrentQueue\u003Cstring>();\nvar cts = new CancellationTokenSource();\n\n// Producer: генерує повідомлення\nvar producer = Task.Run(() =>\n{\n    int messageId = 0;\n    while (!cts.Token.IsCancellationRequested)\n    {\n        string message = $\"Message-{messageId++}\";\n        queue.Enqueue(message);\n        Console.WriteLine($\"[Producer] Enqueued: {message}\");\n        Thread.Sleep(Random.Shared.Next(50, 150));\n    }\n});\n\n// Consumer: обробляє повідомлення\nvar consumer = Task.Run(() =>\n{\n    while (!cts.Token.IsCancellationRequested)\n    {\n        if (queue.TryDequeue(out string? message))\n        {\n            Console.WriteLine($\"[Consumer] Processing: {message}\");\n            Thread.Sleep(Random.Shared.Next(100, 200));  // Симуляція обробки\n        }\n        else\n        {\n            Thread.Sleep(10);  // Черга порожня, трохи почекати\n        }\n    }\n});\n\n// Працюємо 5 секунд\nawait Task.Delay(5000);\ncts.Cancel();\n\nawait Task.WhenAll(producer, consumer);\nConsole.WriteLine($\"Final queue count: {queue.Count}\");\n","ProducerConsumer.cs",[2968,9467,9468,9476,9492,9504,9520,9524,9542,9558,9562,9567,9587,9591,9604,9625,9629,9655,9671,9694,9728,9732,9736,9740,9745,9762,9766,9784,9788,9813,9817,9840,9875,9879,9884,9888,9905,9909,9913,9917,9921,9926,9946,9957,9961,9984],{"__ignoreMap":3051},[3055,9469,9470,9472,9474],{"class":3057,"line":3058},[3055,9471,3062],{"class":3061},[3055,9473,3066],{"class":3065},[3055,9475,3070],{"class":3069},[3055,9477,9478,9480,9482,9484,9486,9488,9490],{"class":3057,"line":3073},[3055,9479,3062],{"class":3061},[3055,9481,3066],{"class":3065},[3055,9483,3080],{"class":3069},[3055,9485,3083],{"class":3065},[3055,9487,3080],{"class":3069},[3055,9489,6738],{"class":3065},[3055,9491,3070],{"class":3069},[3055,9493,9494,9496,9498,9500,9502],{"class":3057,"line":3093},[3055,9495,3062],{"class":3061},[3055,9497,3066],{"class":3065},[3055,9499,3080],{"class":3069},[3055,9501,3102],{"class":3065},[3055,9503,3070],{"class":3069},[3055,9505,9506,9508,9510,9512,9514,9516,9518],{"class":3057,"line":3112},[3055,9507,3062],{"class":3061},[3055,9509,3066],{"class":3065},[3055,9511,3080],{"class":3069},[3055,9513,3102],{"class":3065},[3055,9515,3080],{"class":3069},[3055,9517,3107],{"class":3065},[3055,9519,3070],{"class":3069},[3055,9521,9522],{"class":3057,"line":3119},[3055,9523,3116],{"emptyLinePlaceholder":3115},[3055,9525,9526,9528,9530,9532,9534,9536,9538,9540],{"class":3057,"line":3148},[3055,9527,3123],{"class":3122},[3055,9529,9159],{"class":3126},[3055,9531,3130],{"class":3069},[3055,9533,3133],{"class":3122},[3055,9535,9166],{"class":3065},[3055,9537,3139],{"class":3069},[3055,9539,3580],{"class":3122},[3055,9541,3145],{"class":3069},[3055,9543,9544,9546,9549,9551,9553,9556],{"class":3057,"line":3153},[3055,9545,3123],{"class":3122},[3055,9547,9548],{"class":3126}," cts",[3055,9550,3130],{"class":3069},[3055,9552,3133],{"class":3122},[3055,9554,9555],{"class":3065}," CancellationTokenSource",[3055,9557,4071],{"class":3069},[3055,9559,9560],{"class":3057,"line":3160},[3055,9561,3116],{"emptyLinePlaceholder":3115},[3055,9563,9564],{"class":3057,"line":3192},[3055,9565,9566],{"class":3156},"// Producer: генерує повідомлення\n",[3055,9568,9569,9571,9574,9576,9579,9581,9584],{"class":3057,"line":3198},[3055,9570,3123],{"class":3122},[3055,9572,9573],{"class":3126}," producer",[3055,9575,3130],{"class":3069},[3055,9577,9578],{"class":3126},"Task",[3055,9580,3080],{"class":3069},[3055,9582,9583],{"class":3168},"Run",[3055,9585,9586],{"class":3069},"(() =>\n",[3055,9588,9589],{"class":3057,"line":3235},[3055,9590,3195],{"class":3069},[3055,9592,9593,9595,9598,9600,9602],{"class":3057,"line":3241},[3055,9594,8947],{"class":3122},[3055,9596,9597],{"class":3126}," messageId",[3055,9599,3130],{"class":3069},[3055,9601,3176],{"class":3175},[3055,9603,3070],{"class":3069},[3055,9605,9606,9608,9610,9613,9615,9618,9620,9623],{"class":3057,"line":3272},[3055,9607,6353],{"class":3061},[3055,9609,6372],{"class":3069},[3055,9611,9612],{"class":3126},"cts",[3055,9614,3080],{"class":3069},[3055,9616,9617],{"class":3126},"Token",[3055,9619,3080],{"class":3069},[3055,9621,9622],{"class":3126},"IsCancellationRequested",[3055,9624,3384],{"class":3069},[3055,9626,9627],{"class":3057,"line":3278},[3055,9628,3238],{"class":3069},[3055,9630,9631,9633,9636,9638,9641,9643,9646,9649,9651,9653],{"class":3057,"line":3284},[3055,9632,4143],{"class":3122},[3055,9634,9635],{"class":3126}," message",[3055,9637,3130],{"class":3069},[3055,9639,9640],{"class":3302},"$\"Message-",[3055,9642,3307],{"class":3306},[3055,9644,9645],{"class":3126},"messageId",[3055,9647,9648],{"class":3069},"++",[3055,9650,3318],{"class":3306},[3055,9652,3321],{"class":3302},[3055,9654,3070],{"class":3069},[3055,9656,9657,9660,9662,9664,9666,9669],{"class":3057,"line":3289},[3055,9658,9659],{"class":3126},"        queue",[3055,9661,3080],{"class":3069},[3055,9663,9095],{"class":3168},[3055,9665,3172],{"class":3069},[3055,9667,9668],{"class":3126},"message",[3055,9670,3324],{"class":3069},[3055,9672,9673,9675,9677,9679,9681,9684,9686,9688,9690,9692],{"class":3057,"line":3327},[3055,9674,5416],{"class":3126},[3055,9676,3080],{"class":3069},[3055,9678,3297],{"class":3168},[3055,9680,3172],{"class":3069},[3055,9682,9683],{"class":3302},"$\"[Producer] Enqueued: ",[3055,9685,3307],{"class":3306},[3055,9687,9668],{"class":3126},[3055,9689,3318],{"class":3306},[3055,9691,3321],{"class":3302},[3055,9693,3324],{"class":3069},[3055,9695,9696,9698,9700,9702,9704,9707,9709,9712,9714,9717,9719,9721,9723,9726],{"class":3057,"line":3333},[3055,9697,7765],{"class":3126},[3055,9699,3080],{"class":3069},[3055,9701,7770],{"class":3168},[3055,9703,3172],{"class":3069},[3055,9705,9706],{"class":3126},"Random",[3055,9708,3080],{"class":3069},[3055,9710,9711],{"class":3126},"Shared",[3055,9713,3080],{"class":3069},[3055,9715,9716],{"class":3168},"Next",[3055,9718,3172],{"class":3069},[3055,9720,5295],{"class":3175},[3055,9722,2971],{"class":3069},[3055,9724,9725],{"class":3175},"150",[3055,9727,7623],{"class":3069},[3055,9729,9730],{"class":3057,"line":3338},[3055,9731,3275],{"class":3069},[3055,9733,9734],{"class":3057,"line":3755},[3055,9735,3281],{"class":3069},[3055,9737,9738],{"class":3057,"line":3760},[3055,9739,3116],{"emptyLinePlaceholder":3115},[3055,9741,9742],{"class":3057,"line":3797},[3055,9743,9744],{"class":3156},"// Consumer: обробляє повідомлення\n",[3055,9746,9747,9749,9752,9754,9756,9758,9760],{"class":3057,"line":3826},[3055,9748,3123],{"class":3122},[3055,9750,9751],{"class":3126}," consumer",[3055,9753,3130],{"class":3069},[3055,9755,9578],{"class":3126},[3055,9757,3080],{"class":3069},[3055,9759,9583],{"class":3168},[3055,9761,9586],{"class":3069},[3055,9763,9764],{"class":3057,"line":3831},[3055,9765,3195],{"class":3069},[3055,9767,9768,9770,9772,9774,9776,9778,9780,9782],{"class":3057,"line":3836},[3055,9769,6353],{"class":3061},[3055,9771,6372],{"class":3069},[3055,9773,9612],{"class":3126},[3055,9775,3080],{"class":3069},[3055,9777,9617],{"class":3126},[3055,9779,3080],{"class":3069},[3055,9781,9622],{"class":3126},[3055,9783,3384],{"class":3069},[3055,9785,9786],{"class":3057,"line":3842},[3055,9787,3238],{"class":3069},[3055,9789,9790,9792,9794,9796,9798,9800,9802,9804,9807,9809,9811],{"class":3057,"line":3848},[3055,9791,6369],{"class":3061},[3055,9793,3204],{"class":3069},[3055,9795,9186],{"class":3126},[3055,9797,3080],{"class":3069},[3055,9799,9105],{"class":3168},[3055,9801,3172],{"class":3069},[3055,9803,4906],{"class":3122},[3055,9805,9806],{"class":3122}," string",[3055,9808,6940],{"class":3069},[3055,9810,9668],{"class":3126},[3055,9812,4915],{"class":3069},[3055,9814,9815],{"class":3057,"line":3854},[3055,9816,3665],{"class":3069},[3055,9818,9819,9821,9823,9825,9827,9830,9832,9834,9836,9838],{"class":3057,"line":4603},[3055,9820,8418],{"class":3126},[3055,9822,3080],{"class":3069},[3055,9824,3297],{"class":3168},[3055,9826,3172],{"class":3069},[3055,9828,9829],{"class":3302},"$\"[Consumer] Processing: ",[3055,9831,3307],{"class":3306},[3055,9833,9668],{"class":3126},[3055,9835,3318],{"class":3306},[3055,9837,3321],{"class":3302},[3055,9839,3324],{"class":3069},[3055,9841,9842,9845,9847,9849,9851,9853,9855,9857,9859,9861,9863,9865,9867,9869,9872],{"class":3057,"line":4609},[3055,9843,9844],{"class":3126},"            Thread",[3055,9846,3080],{"class":3069},[3055,9848,7770],{"class":3168},[3055,9850,3172],{"class":3069},[3055,9852,9706],{"class":3126},[3055,9854,3080],{"class":3069},[3055,9856,9711],{"class":3126},[3055,9858,3080],{"class":3069},[3055,9860,9716],{"class":3168},[3055,9862,3172],{"class":3069},[3055,9864,4693],{"class":3175},[3055,9866,2971],{"class":3069},[3055,9868,4752],{"class":3175},[3055,9870,9871],{"class":3069},"));  ",[3055,9873,9874],{"class":3156},"// Симуляція обробки\n",[3055,9876,9877],{"class":3057,"line":7082},[3055,9878,3728],{"class":3069},[3055,9880,9881],{"class":3057,"line":7095},[3055,9882,9883],{"class":3061},"        else\n",[3055,9885,9886],{"class":3057,"line":7104},[3055,9887,3665],{"class":3069},[3055,9889,9890,9892,9894,9896,9898,9900,9902],{"class":3057,"line":7109},[3055,9891,9844],{"class":3126},[3055,9893,3080],{"class":3069},[3055,9895,7770],{"class":3168},[3055,9897,3172],{"class":3069},[3055,9899,3181],{"class":3175},[3055,9901,3266],{"class":3069},[3055,9903,9904],{"class":3156},"// Черга порожня, трохи почекати\n",[3055,9906,9907],{"class":3057,"line":7114},[3055,9908,3728],{"class":3069},[3055,9910,9911],{"class":3057,"line":7152},[3055,9912,3275],{"class":3069},[3055,9914,9915],{"class":3057,"line":7157},[3055,9916,3281],{"class":3069},[3055,9918,9919],{"class":3057,"line":7187},[3055,9920,3116],{"emptyLinePlaceholder":3115},[3055,9922,9923],{"class":3057,"line":7211},[3055,9924,9925],{"class":3156},"// Працюємо 5 секунд\n",[3055,9927,9928,9931,9934,9936,9939,9941,9944],{"class":3057,"line":7216},[3055,9929,9930],{"class":3122},"await",[3055,9932,9933],{"class":3126}," Task",[3055,9935,3080],{"class":3069},[3055,9937,9938],{"class":3168},"Delay",[3055,9940,3172],{"class":3069},[3055,9942,9943],{"class":3175},"5000",[3055,9945,3324],{"class":3069},[3055,9947,9948,9950,9952,9955],{"class":3057,"line":7235},[3055,9949,9612],{"class":3126},[3055,9951,3080],{"class":3069},[3055,9953,9954],{"class":3168},"Cancel",[3055,9956,4071],{"class":3069},[3055,9958,9959],{"class":3057,"line":7240},[3055,9960,3116],{"emptyLinePlaceholder":3115},[3055,9962,9963,9965,9967,9969,9972,9974,9977,9979,9982],{"class":3057,"line":7245},[3055,9964,9930],{"class":3122},[3055,9966,9933],{"class":3126},[3055,9968,3080],{"class":3069},[3055,9970,9971],{"class":3168},"WhenAll",[3055,9973,3172],{"class":3069},[3055,9975,9976],{"class":3126},"producer",[3055,9978,2971],{"class":3069},[3055,9980,9981],{"class":3126},"consumer",[3055,9983,3324],{"class":3069},[3055,9985,9986,9988,9990,9992,9994,9997,9999,10001,10003,10005,10007,10009],{"class":3057,"line":7293},[3055,9987,3292],{"class":3126},[3055,9989,3080],{"class":3069},[3055,9991,3297],{"class":3168},[3055,9993,3172],{"class":3069},[3055,9995,9996],{"class":3302},"$\"Final queue count: ",[3055,9998,3307],{"class":3306},[3055,10000,9186],{"class":3126},[3055,10002,3080],{"class":3306},[3055,10004,3315],{"class":3126},[3055,10006,3318],{"class":3306},[3055,10008,3321],{"class":3302},[3055,10010,3324],{"class":3069},[3025,10012],{},[2959,10014,10016,10017],{"id":10015},"concurrentstack-lock-free-lifo","ConcurrentStack",[3037,10018,10019],{}," — Lock-Free LIFO",[3032,10021,10023],{"id":10022},"архітектура-lock-free-linked-list-single-head","Архітектура: Lock-Free Linked List (Single Head)",[2964,10025,10026,9448,10029,10032,10033,3490],{},[2968,10027,10028],{},"ConcurrentStack\u003CT>",[2977,10030,10031],{},"lock-free stack"," через linked list з ",[2977,10034,10035],{},"одним head вказівником",[3044,10037,10040],{"className":10038,"code":10039,"language":3496},[3494],"     head\n       ↓\n    ┌──────┐\n    │ Node │\n    │  D   │  ← Push/Pop тут (вершина)\n    └──┬───┘\n       ↓\n    ┌──────┐\n    │ Node │\n    │  C   │\n    └──┬───┘\n       ↓\n    ┌──────┐\n    │ Node │\n    │  B   │\n    └──┬───┘\n       ↓\n    ┌──────┐\n    │ Node │\n    │  A   │\n    └──┬───┘\n       ↓\n      null\n",[2968,10041,10039],{"__ignoreMap":3051},[2964,10043,10044,3490],{},[2977,10045,10046],{},"Операції",[3009,10048,10049,10055,10061],{},[3012,10050,10051,10054],{},[2968,10052,10053],{},"Push"," — додає на вершину (атомарно через CAS)",[3012,10056,10057,10060],{},[2968,10058,10059],{},"TryPop"," — забирає з вершини (атомарно через CAS)",[3012,10062,9113,10063],{},[2977,10064,9116],{},[3032,10066,4622],{"id":10067},"основні-методи-2",[3044,10069,10072],{"className":3046,"code":10070,"filename":10071,"language":3049,"meta":3050,"style":3051},"using System.Collections.Concurrent;\n\nvar stack = new ConcurrentStack\u003Cint>();\n\n// Push — додати елемент\nstack.Push(1);\nstack.Push(2);\nstack.Push(3);\n\n// TryPop — забрати елемент\nif (stack.TryPop(out int result))\n{\n    Console.WriteLine($\"Popped: {result}\");  // 3 (LIFO)\n}\n\n// TryPeek — подивитись без видалення\nif (stack.TryPeek(out int peeked))\n{\n    Console.WriteLine($\"Peeked: {peeked}\");  // 2\n}\n\n// PushRange — додати кілька елементів одразу (ефективніше)\nint[] items = { 10, 20, 30 };\nstack.PushRange(items);\n\n// TryPopRange — забрати кілька елементів одразу\nint[] buffer = new int[2];\nint popped = stack.TryPopRange(buffer);\nConsole.WriteLine($\"Popped {popped} items: {string.Join(\", \", buffer)}\");\n// Popped 2 items: 30, 20\n","ConcurrentStackBasics.cs",[2968,10073,10074,10090,10094,10114,10118,10123,10138,10152,10166,10170,10175,10197,10201,10227,10231,10235,10239,10261,10265,10289,10293,10297,10302,10330,10345,10349,10354,10376,10398,10445],{"__ignoreMap":3051},[3055,10075,10076,10078,10080,10082,10084,10086,10088],{"class":3057,"line":3058},[3055,10077,3062],{"class":3061},[3055,10079,3066],{"class":3065},[3055,10081,3080],{"class":3069},[3055,10083,3083],{"class":3065},[3055,10085,3080],{"class":3069},[3055,10087,6738],{"class":3065},[3055,10089,3070],{"class":3069},[3055,10091,10092],{"class":3057,"line":3073},[3055,10093,3116],{"emptyLinePlaceholder":3115},[3055,10095,10096,10098,10101,10103,10105,10108,10110,10112],{"class":3057,"line":3093},[3055,10097,3123],{"class":3122},[3055,10099,10100],{"class":3126}," stack",[3055,10102,3130],{"class":3069},[3055,10104,3133],{"class":3122},[3055,10106,10107],{"class":3065}," ConcurrentStack",[3055,10109,3139],{"class":3069},[3055,10111,3142],{"class":3122},[3055,10113,3145],{"class":3069},[3055,10115,10116],{"class":3057,"line":3112},[3055,10117,3116],{"emptyLinePlaceholder":3115},[3055,10119,10120],{"class":3057,"line":3119},[3055,10121,10122],{"class":3156},"// Push — додати елемент\n",[3055,10124,10125,10128,10130,10132,10134,10136],{"class":3057,"line":3148},[3055,10126,10127],{"class":3126},"stack",[3055,10129,3080],{"class":3069},[3055,10131,10053],{"class":3168},[3055,10133,3172],{"class":3069},[3055,10135,3433],{"class":3175},[3055,10137,3324],{"class":3069},[3055,10139,10140,10142,10144,10146,10148,10150],{"class":3057,"line":3153},[3055,10141,10127],{"class":3126},[3055,10143,3080],{"class":3069},[3055,10145,10053],{"class":3168},[3055,10147,3172],{"class":3069},[3055,10149,5278],{"class":3175},[3055,10151,3324],{"class":3069},[3055,10153,10154,10156,10158,10160,10162,10164],{"class":3057,"line":3160},[3055,10155,10127],{"class":3126},[3055,10157,3080],{"class":3069},[3055,10159,10053],{"class":3168},[3055,10161,3172],{"class":3069},[3055,10163,9223],{"class":3175},[3055,10165,3324],{"class":3069},[3055,10167,10168],{"class":3057,"line":3192},[3055,10169,3116],{"emptyLinePlaceholder":3115},[3055,10171,10172],{"class":3057,"line":3198},[3055,10173,10174],{"class":3156},"// TryPop — забрати елемент\n",[3055,10176,10177,10179,10181,10183,10185,10187,10189,10191,10193,10195],{"class":3057,"line":3235},[3055,10178,4888],{"class":3061},[3055,10180,3204],{"class":3069},[3055,10182,10127],{"class":3126},[3055,10184,3080],{"class":3069},[3055,10186,10059],{"class":3168},[3055,10188,3172],{"class":3069},[3055,10190,4906],{"class":3122},[3055,10192,4909],{"class":3122},[3055,10194,9255],{"class":3126},[3055,10196,4915],{"class":3069},[3055,10198,10199],{"class":3057,"line":3241},[3055,10200,3195],{"class":3069},[3055,10202,10203,10205,10207,10209,10211,10214,10216,10218,10220,10222,10224],{"class":3057,"line":3272},[3055,10204,3763],{"class":3126},[3055,10206,3080],{"class":3069},[3055,10208,3297],{"class":3168},[3055,10210,3172],{"class":3069},[3055,10212,10213],{"class":3302},"$\"Popped: ",[3055,10215,3307],{"class":3306},[3055,10217,9279],{"class":3126},[3055,10219,3318],{"class":3306},[3055,10221,3321],{"class":3302},[3055,10223,3266],{"class":3069},[3055,10225,10226],{"class":3156},"// 3 (LIFO)\n",[3055,10228,10229],{"class":3057,"line":3278},[3055,10230,3484],{"class":3069},[3055,10232,10233],{"class":3057,"line":3284},[3055,10234,3116],{"emptyLinePlaceholder":3115},[3055,10236,10237],{"class":3057,"line":3289},[3055,10238,9301],{"class":3156},[3055,10240,10241,10243,10245,10247,10249,10251,10253,10255,10257,10259],{"class":3057,"line":3327},[3055,10242,4888],{"class":3061},[3055,10244,3204],{"class":3069},[3055,10246,10127],{"class":3126},[3055,10248,3080],{"class":3069},[3055,10250,9314],{"class":3168},[3055,10252,3172],{"class":3069},[3055,10254,4906],{"class":3122},[3055,10256,4909],{"class":3122},[3055,10258,9323],{"class":3126},[3055,10260,4915],{"class":3069},[3055,10262,10263],{"class":3057,"line":3333},[3055,10264,3195],{"class":3069},[3055,10266,10267,10269,10271,10273,10275,10277,10279,10281,10283,10285,10287],{"class":3057,"line":3338},[3055,10268,3763],{"class":3126},[3055,10270,3080],{"class":3069},[3055,10272,3297],{"class":3168},[3055,10274,3172],{"class":3069},[3055,10276,9342],{"class":3302},[3055,10278,3307],{"class":3306},[3055,10280,9347],{"class":3126},[3055,10282,3318],{"class":3306},[3055,10284,3321],{"class":3302},[3055,10286,3266],{"class":3069},[3055,10288,9356],{"class":3156},[3055,10290,10291],{"class":3057,"line":3755},[3055,10292,3484],{"class":3069},[3055,10294,10295],{"class":3057,"line":3760},[3055,10296,3116],{"emptyLinePlaceholder":3115},[3055,10298,10299],{"class":3057,"line":3797},[3055,10300,10301],{"class":3156},"// PushRange — додати кілька елементів одразу (ефективніше)\n",[3055,10303,10304,10306,10309,10312,10315,10317,10319,10322,10324,10327],{"class":3057,"line":3826},[3055,10305,3142],{"class":3122},[3055,10307,10308],{"class":3069},"[] ",[3055,10310,10311],{"class":3126},"items",[3055,10313,10314],{"class":3069}," = { ",[3055,10316,3181],{"class":3175},[3055,10318,2971],{"class":3069},[3055,10320,10321],{"class":3175},"20",[3055,10323,2971],{"class":3069},[3055,10325,10326],{"class":3175},"30",[3055,10328,10329],{"class":3069}," };\n",[3055,10331,10332,10334,10336,10339,10341,10343],{"class":3057,"line":3831},[3055,10333,10127],{"class":3126},[3055,10335,3080],{"class":3069},[3055,10337,10338],{"class":3168},"PushRange",[3055,10340,3172],{"class":3069},[3055,10342,10311],{"class":3126},[3055,10344,3324],{"class":3069},[3055,10346,10347],{"class":3057,"line":3836},[3055,10348,3116],{"emptyLinePlaceholder":3115},[3055,10350,10351],{"class":3057,"line":3842},[3055,10352,10353],{"class":3156},"// TryPopRange — забрати кілька елементів одразу\n",[3055,10355,10356,10358,10360,10363,10365,10367,10369,10371,10373],{"class":3057,"line":3848},[3055,10357,3142],{"class":3122},[3055,10359,10308],{"class":3069},[3055,10361,10362],{"class":3126},"buffer",[3055,10364,3130],{"class":3069},[3055,10366,3133],{"class":3122},[3055,10368,4909],{"class":3122},[3055,10370,3454],{"class":3069},[3055,10372,5278],{"class":3175},[3055,10374,10375],{"class":3069},"];\n",[3055,10377,10378,10380,10383,10385,10387,10389,10392,10394,10396],{"class":3057,"line":3854},[3055,10379,3142],{"class":3122},[3055,10381,10382],{"class":3126}," popped",[3055,10384,3130],{"class":3069},[3055,10386,10127],{"class":3126},[3055,10388,3080],{"class":3069},[3055,10390,10391],{"class":3168},"TryPopRange",[3055,10393,3172],{"class":3069},[3055,10395,10362],{"class":3126},[3055,10397,3324],{"class":3069},[3055,10399,10400,10402,10404,10406,10408,10411,10413,10416,10418,10421,10423,10425,10427,10430,10432,10435,10437,10439,10441,10443],{"class":3057,"line":4603},[3055,10401,3292],{"class":3126},[3055,10403,3080],{"class":3069},[3055,10405,3297],{"class":3168},[3055,10407,3172],{"class":3069},[3055,10409,10410],{"class":3302},"$\"Popped ",[3055,10412,3307],{"class":3306},[3055,10414,10415],{"class":3126},"popped",[3055,10417,3318],{"class":3306},[3055,10419,10420],{"class":3302}," items: ",[3055,10422,3307],{"class":3306},[3055,10424,3580],{"class":3122},[3055,10426,3080],{"class":3306},[3055,10428,10429],{"class":3168},"Join",[3055,10431,3172],{"class":3306},[3055,10433,10434],{"class":3302},"\", \"",[3055,10436,2971],{"class":3306},[3055,10438,10362],{"class":3126},[3055,10440,8726],{"class":3306},[3055,10442,3321],{"class":3302},[3055,10444,3324],{"class":3069},[3055,10446,10447],{"class":3057,"line":4609},[3055,10448,10449],{"class":3156},"// Popped 2 items: 30, 20\n",[3025,10451],{},[2959,10453,10455,10456],{"id":10454},"concurrentbag-thread-local-optimization","ConcurrentBag",[3037,10457,10458],{}," — Thread-Local Optimization",[3032,10460,10462],{"id":10461},"архітектура-thread-local-lists","Архітектура: Thread-Local Lists",[2964,10464,10465,10468,10469,3490],{},[2968,10466,10467],{},"ConcurrentBag\u003CT>"," — унікальна колекція оптимізована для сценарію де ",[2977,10470,10471],{},"той самий потік що додає — також забирає",[3044,10473,10476],{"className":10474,"code":10475,"language":3496},[3494],"┌─────────────────────────────────────────────────┐\n│           ConcurrentBag\u003CT>                      │\n├─────────────────────────────────────────────────┤\n│  Thread 1 Local List:  [A, B, C]               │\n│  Thread 2 Local List:  [D, E]                  │\n│  Thread 3 Local List:  [F, G, H, I]            │\n└─────────────────────────────────────────────────┘\n\nThread 1: Add(X) → йде у Thread 1 Local List (lock-free!)\nThread 1: TryTake() → бере з Thread 1 Local List (lock-free!)\n\nThread 2: TryTake() → спочатку з Thread 2 Local List,\n                      якщо порожня → \"краде\" з Thread 1 або 3\n",[2968,10477,10475],{"__ignoreMap":3051},[2964,10479,10480,3490],{},[2977,10481,4293],{},[3009,10483,10484,10491],{},[3012,10485,10486,10487,10490],{},"Додавання/забирання у ",[2977,10488,10489],{},"власному"," потоці — lock-free",[3012,10492,10493],{},"Мінімальна contention якщо кожен потік працює зі своїми даними",[2964,10495,10496,3490],{},[2977,10497,10498],{},"Недоліки",[3009,10500,10501,10504],{},[3012,10502,10503],{},"Немає гарантованого порядку (ні FIFO, ні LIFO)",[3012,10505,10506],{},"\"Крадіжка\" з інших потоків потребує lock",[3032,10508,10510],{"id":10509},"як-працює-thread-local-optimization-детальний-розбір","Як Працює Thread-Local Optimization: Детальний Розбір",[2964,10512,10513,10515,10516,10519],{},[2968,10514,10467],{}," використовує дуже розумну оптимізацію: кожен потік має свій ",[2977,10517,10518],{},"локальний список"," елементів. Це дозволяє уникнути синхронізації у найпоширенішому сценарії — коли потік додає елементи і сам же їх забирає.",[2964,10521,10522,3490],{},[2977,10523,10524],{},"Внутрішня структура",[3044,10526,10528],{"className":3046,"code":10527,"language":3049,"meta":3051,"style":3051},"// Спрощена концептуальна модель\nclass ConcurrentBag\u003CT>\n{\n    // Кожен потік має свій ThreadLocalList\n    private ThreadLocal\u003CWorkStealingQueue\u003CT>> _locals;\n\n    // Глобальний список всіх thread-local черг\n    private List\u003CWorkStealingQueue\u003CT>> _allQueues;\n}\n",[2968,10529,10530,10535,10550,10554,10559,10583,10587,10592,10613],{"__ignoreMap":3051},[3055,10531,10532],{"class":3057,"line":3058},[3055,10533,10534],{"class":3156},"// Спрощена концептуальна модель\n",[3055,10536,10537,10540,10543,10545,10547],{"class":3057,"line":3073},[3055,10538,10539],{"class":3122},"class",[3055,10541,10542],{"class":3065}," ConcurrentBag",[3055,10544,3139],{"class":3069},[3055,10546,3378],{"class":3065},[3055,10548,10549],{"class":3069},">\n",[3055,10551,10552],{"class":3057,"line":3093},[3055,10553,3195],{"class":3069},[3055,10555,10556],{"class":3057,"line":3112},[3055,10557,10558],{"class":3156},"    // Кожен потік має свій ThreadLocalList\n",[3055,10560,10561,10563,10566,10568,10571,10573,10575,10578,10581],{"class":3057,"line":3119},[3055,10562,6799],{"class":3122},[3055,10564,10565],{"class":3065}," ThreadLocal",[3055,10567,3139],{"class":3069},[3055,10569,10570],{"class":3065},"WorkStealingQueue",[3055,10572,3139],{"class":3069},[3055,10574,3378],{"class":3065},[3055,10576,10577],{"class":3069},">> ",[3055,10579,10580],{"class":3126},"_locals",[3055,10582,3070],{"class":3069},[3055,10584,10585],{"class":3057,"line":3148},[3055,10586,3116],{"emptyLinePlaceholder":3115},[3055,10588,10589],{"class":3057,"line":3153},[3055,10590,10591],{"class":3156},"    // Глобальний список всіх thread-local черг\n",[3055,10593,10594,10596,10598,10600,10602,10604,10606,10608,10611],{"class":3057,"line":3160},[3055,10595,6799],{"class":3122},[3055,10597,3136],{"class":3065},[3055,10599,3139],{"class":3069},[3055,10601,10570],{"class":3065},[3055,10603,3139],{"class":3069},[3055,10605,3378],{"class":3065},[3055,10607,10577],{"class":3069},[3055,10609,10610],{"class":3126},"_allQueues",[3055,10612,3070],{"class":3069},[3055,10614,10615],{"class":3057,"line":3192},[3055,10616,3484],{"class":3069},[2964,10618,10619],{},[2977,10620,10621],{},"Сценарій 1: Додавання у власному потоці (найшвидший)",[3044,10623,10625],{"className":3046,"code":10624,"language":3049,"meta":3051,"style":3051},"// Thread 1 додає елемент\nbag.Add(\"A\");\n\n// Що відбувається:\n// 1. Перевірка: чи є у Thread 1 локальний список? Якщо ні → створити\n// 2. Додати \"A\" у локальний список Thread 1 (lock-free!)\n// 3. Готово — жодної синхронізації!\n",[2968,10626,10627,10632,10648,10652,10657,10662,10667],{"__ignoreMap":3051},[3055,10628,10629],{"class":3057,"line":3058},[3055,10630,10631],{"class":3156},"// Thread 1 додає елемент\n",[3055,10633,10634,10637,10639,10641,10643,10646],{"class":3057,"line":3073},[3055,10635,10636],{"class":3126},"bag",[3055,10638,3080],{"class":3069},[3055,10640,3249],{"class":3168},[3055,10642,3172],{"class":3069},[3055,10644,10645],{"class":3302},"\"A\"",[3055,10647,3324],{"class":3069},[3055,10649,10650],{"class":3057,"line":3093},[3055,10651,3116],{"emptyLinePlaceholder":3115},[3055,10653,10654],{"class":3057,"line":3112},[3055,10655,10656],{"class":3156},"// Що відбувається:\n",[3055,10658,10659],{"class":3057,"line":3119},[3055,10660,10661],{"class":3156},"// 1. Перевірка: чи є у Thread 1 локальний список? Якщо ні → створити\n",[3055,10663,10664],{"class":3057,"line":3148},[3055,10665,10666],{"class":3156},"// 2. Додати \"A\" у локальний список Thread 1 (lock-free!)\n",[3055,10668,10669],{"class":3057,"line":3153},[3055,10670,10671],{"class":3156},"// 3. Готово — жодної синхронізації!\n",[2964,10673,10674],{},[2977,10675,10676],{},"Сценарій 2: Забирання з власного потоку (швидкий)",[3044,10678,10680],{"className":3046,"code":10679,"language":3049,"meta":3051,"style":3051},"// Thread 1 забирає елемент\nif (bag.TryTake(out string? item))\n{\n    Console.WriteLine(item);  // \"A\"\n}\n\n// Що відбувається:\n// 1. Спроба забрати з локального списку Thread 1 (lock-free!)\n// 2. Якщо список не порожній → повернути елемент\n// 3. Готово — жодної синхронізації!\n",[2968,10681,10682,10687,10712,10716,10733,10737,10741,10745,10750,10755],{"__ignoreMap":3051},[3055,10683,10684],{"class":3057,"line":3058},[3055,10685,10686],{"class":3156},"// Thread 1 забирає елемент\n",[3055,10688,10689,10691,10693,10695,10697,10700,10702,10704,10706,10708,10710],{"class":3057,"line":3073},[3055,10690,4888],{"class":3061},[3055,10692,3204],{"class":3069},[3055,10694,10636],{"class":3126},[3055,10696,3080],{"class":3069},[3055,10698,10699],{"class":3168},"TryTake",[3055,10701,3172],{"class":3069},[3055,10703,4906],{"class":3122},[3055,10705,9806],{"class":3122},[3055,10707,6940],{"class":3069},[3055,10709,3462],{"class":3126},[3055,10711,4915],{"class":3069},[3055,10713,10714],{"class":3057,"line":3093},[3055,10715,3195],{"class":3069},[3055,10717,10718,10720,10722,10724,10726,10728,10730],{"class":3057,"line":3112},[3055,10719,3763],{"class":3126},[3055,10721,3080],{"class":3069},[3055,10723,3297],{"class":3168},[3055,10725,3172],{"class":3069},[3055,10727,3462],{"class":3126},[3055,10729,3266],{"class":3069},[3055,10731,10732],{"class":3156},"// \"A\"\n",[3055,10734,10735],{"class":3057,"line":3119},[3055,10736,3484],{"class":3069},[3055,10738,10739],{"class":3057,"line":3148},[3055,10740,3116],{"emptyLinePlaceholder":3115},[3055,10742,10743],{"class":3057,"line":3153},[3055,10744,10656],{"class":3156},[3055,10746,10747],{"class":3057,"line":3160},[3055,10748,10749],{"class":3156},"// 1. Спроба забрати з локального списку Thread 1 (lock-free!)\n",[3055,10751,10752],{"class":3057,"line":3192},[3055,10753,10754],{"class":3156},"// 2. Якщо список не порожній → повернути елемент\n",[3055,10756,10757],{"class":3057,"line":3198},[3055,10758,10671],{"class":3156},[2964,10760,10761],{},[2977,10762,10763],{},"Сценарій 3: \"Крадіжка\" з іншого потоку (повільний)",[3044,10765,10767],{"className":3046,"code":10766,"language":3049,"meta":3051,"style":3051},"// Thread 2 намагається забрати елемент, але його локальний список порожній\nif (bag.TryTake(out string? item))\n{\n    Console.WriteLine(item);  // \"A\" (вкрадено з Thread 1!)\n}\n\n// Що відбувається:\n// 1. Локальний список Thread 2 порожній\n// 2. Перебір всіх інших thread-local списків\n// 3. Знайдено непорожній список Thread 1\n// 4. Захоплення lock на список Thread 1\n// 5. \"Крадіжка\" елемента з Thread 1\n// 6. Звільнення lock\n",[2968,10768,10769,10774,10798,10802,10819,10823,10827,10831,10836,10841,10846,10851,10856],{"__ignoreMap":3051},[3055,10770,10771],{"class":3057,"line":3058},[3055,10772,10773],{"class":3156},"// Thread 2 намагається забрати елемент, але його локальний список порожній\n",[3055,10775,10776,10778,10780,10782,10784,10786,10788,10790,10792,10794,10796],{"class":3057,"line":3073},[3055,10777,4888],{"class":3061},[3055,10779,3204],{"class":3069},[3055,10781,10636],{"class":3126},[3055,10783,3080],{"class":3069},[3055,10785,10699],{"class":3168},[3055,10787,3172],{"class":3069},[3055,10789,4906],{"class":3122},[3055,10791,9806],{"class":3122},[3055,10793,6940],{"class":3069},[3055,10795,3462],{"class":3126},[3055,10797,4915],{"class":3069},[3055,10799,10800],{"class":3057,"line":3093},[3055,10801,3195],{"class":3069},[3055,10803,10804,10806,10808,10810,10812,10814,10816],{"class":3057,"line":3112},[3055,10805,3763],{"class":3126},[3055,10807,3080],{"class":3069},[3055,10809,3297],{"class":3168},[3055,10811,3172],{"class":3069},[3055,10813,3462],{"class":3126},[3055,10815,3266],{"class":3069},[3055,10817,10818],{"class":3156},"// \"A\" (вкрадено з Thread 1!)\n",[3055,10820,10821],{"class":3057,"line":3119},[3055,10822,3484],{"class":3069},[3055,10824,10825],{"class":3057,"line":3148},[3055,10826,3116],{"emptyLinePlaceholder":3115},[3055,10828,10829],{"class":3057,"line":3153},[3055,10830,10656],{"class":3156},[3055,10832,10833],{"class":3057,"line":3160},[3055,10834,10835],{"class":3156},"// 1. Локальний список Thread 2 порожній\n",[3055,10837,10838],{"class":3057,"line":3192},[3055,10839,10840],{"class":3156},"// 2. Перебір всіх інших thread-local списків\n",[3055,10842,10843],{"class":3057,"line":3198},[3055,10844,10845],{"class":3156},"// 3. Знайдено непорожній список Thread 1\n",[3055,10847,10848],{"class":3057,"line":3235},[3055,10849,10850],{"class":3156},"// 4. Захоплення lock на список Thread 1\n",[3055,10852,10853],{"class":3057,"line":3241},[3055,10854,10855],{"class":3156},"// 5. \"Крадіжка\" елемента з Thread 1\n",[3055,10857,10858],{"class":3057,"line":3272},[3055,10859,10860],{"class":3156},"// 6. Звільнення lock\n",[2964,10862,10863,3490],{},[2977,10864,4465],{},[3917,10866,10867],{},[3044,10868,10870],{"className":3921,"code":10869,"language":3917,"meta":3051,"style":3051},"sequenceDiagram\n    participant T1 as Thread 1\n    participant L1 as Local List 1\n    participant T2 as Thread 2\n    participant L2 as Local List 2\n\n    Note over T1,L2: Сценарій: Thread 1 додає, Thread 2 краде\n\n    T1->>L1: Add(\"A\")\n    Note over L1: [\"A\"]\u003Cbr/>Lock-free!\n\n    T1->>L1: Add(\"B\")\n    Note over L1: [\"A\", \"B\"]\u003Cbr/>Lock-free!\n\n    T2->>L2: TryTake()\n    Note over L2: Порожній!\n\n    T2->>L1: Спроба \"вкрасти\"\n    Note over L1: Захоплення lock...\n    L1->>T2: Повернуто \"B\"\n    Note over L1: [\"A\"]\n\n    T1->>L1: TryTake()\n    Note over L1: [\"A\"] → []\u003Cbr/>Lock-free!\n    L1->>T1: Повернуто \"A\"\n",[2968,10871,10872,10876,10880,10885,10889,10894,10898,10903,10907,10912,10917,10921,10926,10931,10935,10940,10945,10949,10954,10959,10964,10969,10973,10978,10983],{"__ignoreMap":3051},[3055,10873,10874],{"class":3057,"line":3058},[3055,10875,3929],{},[3055,10877,10878],{"class":3057,"line":3073},[3055,10879,3934],{},[3055,10881,10882],{"class":3057,"line":3093},[3055,10883,10884],{},"    participant L1 as Local List 1\n",[3055,10886,10887],{"class":3057,"line":3112},[3055,10888,3939],{},[3055,10890,10891],{"class":3057,"line":3119},[3055,10892,10893],{},"    participant L2 as Local List 2\n",[3055,10895,10896],{"class":3057,"line":3148},[3055,10897,3116],{"emptyLinePlaceholder":3115},[3055,10899,10900],{"class":3057,"line":3153},[3055,10901,10902],{},"    Note over T1,L2: Сценарій: Thread 1 додає, Thread 2 краде\n",[3055,10904,10905],{"class":3057,"line":3160},[3055,10906,3116],{"emptyLinePlaceholder":3115},[3055,10908,10909],{"class":3057,"line":3192},[3055,10910,10911],{},"    T1->>L1: Add(\"A\")\n",[3055,10913,10914],{"class":3057,"line":3198},[3055,10915,10916],{},"    Note over L1: [\"A\"]\u003Cbr/>Lock-free!\n",[3055,10918,10919],{"class":3057,"line":3235},[3055,10920,3116],{"emptyLinePlaceholder":3115},[3055,10922,10923],{"class":3057,"line":3241},[3055,10924,10925],{},"    T1->>L1: Add(\"B\")\n",[3055,10927,10928],{"class":3057,"line":3272},[3055,10929,10930],{},"    Note over L1: [\"A\", \"B\"]\u003Cbr/>Lock-free!\n",[3055,10932,10933],{"class":3057,"line":3278},[3055,10934,3116],{"emptyLinePlaceholder":3115},[3055,10936,10937],{"class":3057,"line":3284},[3055,10938,10939],{},"    T2->>L2: TryTake()\n",[3055,10941,10942],{"class":3057,"line":3289},[3055,10943,10944],{},"    Note over L2: Порожній!\n",[3055,10946,10947],{"class":3057,"line":3327},[3055,10948,3116],{"emptyLinePlaceholder":3115},[3055,10950,10951],{"class":3057,"line":3333},[3055,10952,10953],{},"    T2->>L1: Спроба \"вкрасти\"\n",[3055,10955,10956],{"class":3057,"line":3338},[3055,10957,10958],{},"    Note over L1: Захоплення lock...\n",[3055,10960,10961],{"class":3057,"line":3755},[3055,10962,10963],{},"    L1->>T2: Повернуто \"B\"\n",[3055,10965,10966],{"class":3057,"line":3760},[3055,10967,10968],{},"    Note over L1: [\"A\"]\n",[3055,10970,10971],{"class":3057,"line":3797},[3055,10972,3116],{"emptyLinePlaceholder":3115},[3055,10974,10975],{"class":3057,"line":3826},[3055,10976,10977],{},"    T1->>L1: TryTake()\n",[3055,10979,10980],{"class":3057,"line":3831},[3055,10981,10982],{},"    Note over L1: [\"A\"] → []\u003Cbr/>Lock-free!\n",[3055,10984,10985],{"class":3057,"line":3836},[3055,10986,10987],{},"    L1->>T1: Повернуто \"A\"\n",[2964,10989,10990],{},[2977,10991,10992],{},"Чому це ефективно для Parallel.ForEach?",[2964,10994,10995,10996,10998],{},"У типовому сценарії ",[2968,10997,8894],{},", кожен worker потік:",[3877,11000,11001,11004,11013],{},[3012,11002,11003],{},"Отримує свою порцію роботи (наприклад, файли для обробки)",[3012,11005,11006,11007,11010,11011],{},"Обробляє їх та ",[2977,11008,11009],{},"додає"," результати у ",[2968,11012,10455],{},[3012,11014,11015,11018],{},[2977,11016,11017],{},"НЕ забирає"," елементи під час обробки",[2964,11020,11021,11022,11025,11026,11029],{},"Після завершення всіх потоків, головний потік забирає всі результати через ",[2968,11023,11024],{},"ToArray()"," або ",[2968,11027,11028],{},"ToList()",". У цьому сценарії:",[3009,11031,11032,11042,11045],{},[3012,11033,11034,11035,11038,11039,11041],{},"Всі ",[2968,11036,11037],{},"Add()"," операції — ",[2977,11040,9116],{}," (кожен потік додає у свій список)",[3012,11043,11044],{},"Жодної \"крадіжки\" під час обробки",[3012,11046,11047],{},"Мінімальна contention",[2964,11049,11050,3490],{},[2977,11051,11052],{},"Benchmark: ConcurrentBag vs ConcurrentQueue для Parallel.ForEach",[3044,11054,11056],{"className":3046,"code":11055,"language":3049,"meta":3051,"style":3051},"// Тест: 10,000 ітерацій, 8 потоків, кожен додає 1000 елементів\nConcurrentQueue:  ~45ms\nConcurrentBag:    ~28ms  (в 1.6x швидше!)\n",[2968,11057,11058,11063,11074],{"__ignoreMap":3051},[3055,11059,11060],{"class":3057,"line":3058},[3055,11061,11062],{"class":3156},"// Тест: 10,000 ітерацій, 8 потоків, кожен додає 1000 елементів\n",[3055,11064,11065,11068,11071],{"class":3057,"line":3073},[3055,11066,9058],{"class":11067},"s5IvJ",[3055,11069,11070],{"class":3069},":  ~",[3055,11072,11073],{"class":9045},"45ms\n",[3055,11075,11076,11078,11081,11084,11087,11089,11092,11094],{"class":3057,"line":3093},[3055,11077,10455],{"class":11067},[3055,11079,11080],{"class":3069},":    ~",[3055,11082,11083],{"class":9045},"28ms",[3055,11085,11086],{"class":3069},"  (",[3055,11088,9042],{"class":3126},[3055,11090,11091],{"class":9045}," 1.6x",[3055,11093,9049],{"class":3126},[3055,11095,9052],{"class":3069},[3032,11097,11099],{"id":11098},"коли-використовувати-concurrentbag","Коли Використовувати ConcurrentBag",[2964,11101,11102,3490],{},[2977,11103,11104],{},"✅ Використовуйте ConcurrentBag коли",[3009,11106,11107,11113,11116,11119],{},[3012,11108,11109,11110,11112],{},"Паралельна обробка з агрегацією результатів (",[2968,11111,8894],{}," + збір результатів)",[3012,11114,11115],{},"Кожен потік додає елементи, але рідко забирає",[3012,11117,11118],{},"Порядок елементів не важливий",[3012,11120,11121],{},"Потрібна максимальна throughput для додавання",[2964,11123,11124,3490],{},[2977,11125,11126],{},"❌ НЕ використовуйте ConcurrentBag коли",[3009,11128,11129,11136,11144],{},[3012,11130,11131,11132,11025,11134],{},"Потрібен FIFO або LIFO порядок → ",[2968,11133,9058],{},[2968,11135,10016],{},[3012,11137,11138,11139,11025,11141],{},"Один потік додає, інший забирає (producer-consumer) → ",[2968,11140,9058],{},[2968,11142,11143],{},"BlockingCollection",[3012,11145,11146,11147],{},"Потрібна \"справедлива\" черга → ",[2968,11148,9058],{},[3032,11150,11152],{"id":11151},"додатковий-приклад-parallel-image-processing","Додатковий Приклад: Parallel Image Processing",[3044,11154,11157],{"className":3046,"code":11155,"filename":11156,"language":3049,"meta":3050,"style":3051},"using System;\nusing System.Collections.Concurrent;\nusing System.IO;\nusing System.Threading.Tasks;\n\nvar imageFiles = Directory.GetFiles(@\"C:\\Images\", \"*.jpg\");\nvar processedImages = new ConcurrentBag\u003Cstring>();\n\nConsole.WriteLine($\"Processing {imageFiles.Length} images...\");\n\nParallel.ForEach(imageFiles, imageFile =>\n{\n    // Симуляція обробки зображення\n    string fileName = Path.GetFileName(imageFile);\n    Console.WriteLine($\"[Thread {Thread.CurrentThread.ManagedThreadId}] Processing: {fileName}\");\n\n    Thread.Sleep(Random.Shared.Next(50, 150));  // Симуляція роботи\n\n    // Додаємо результат у ConcurrentBag (lock-free для цього потоку!)\n    processedImages.Add($\"processed_{fileName}\");\n});\n\nConsole.WriteLine($\"\\nProcessed {processedImages.Count} images\");\n\n// Забираємо всі результати (тут може бути \"крадіжка\", але це одноразова операція)\nvar results = processedImages.ToArray();\nforeach (var result in results.Take(5))\n{\n    Console.WriteLine($\"  - {result}\");\n}\n","ParallelImageProcessing.cs",[2968,11158,11159,11167,11183,11195,11211,11215,11242,11261,11265,11293,11297,11316,11320,11325,11346,11389,11393,11427,11431,11436,11460,11464,11468,11501,11505,11510,11528,11553,11557,11580],{"__ignoreMap":3051},[3055,11160,11161,11163,11165],{"class":3057,"line":3058},[3055,11162,3062],{"class":3061},[3055,11164,3066],{"class":3065},[3055,11166,3070],{"class":3069},[3055,11168,11169,11171,11173,11175,11177,11179,11181],{"class":3057,"line":3073},[3055,11170,3062],{"class":3061},[3055,11172,3066],{"class":3065},[3055,11174,3080],{"class":3069},[3055,11176,3083],{"class":3065},[3055,11178,3080],{"class":3069},[3055,11180,6738],{"class":3065},[3055,11182,3070],{"class":3069},[3055,11184,11185,11187,11189,11191,11193],{"class":3057,"line":3093},[3055,11186,3062],{"class":3061},[3055,11188,3066],{"class":3065},[3055,11190,3080],{"class":3069},[3055,11192,7912],{"class":3065},[3055,11194,3070],{"class":3069},[3055,11196,11197,11199,11201,11203,11205,11207,11209],{"class":3057,"line":3112},[3055,11198,3062],{"class":3061},[3055,11200,3066],{"class":3065},[3055,11202,3080],{"class":3069},[3055,11204,3102],{"class":3065},[3055,11206,3080],{"class":3069},[3055,11208,3107],{"class":3065},[3055,11210,3070],{"class":3069},[3055,11212,11213],{"class":3057,"line":3119},[3055,11214,3116],{"emptyLinePlaceholder":3115},[3055,11216,11217,11219,11222,11224,11226,11228,11230,11232,11235,11237,11240],{"class":3057,"line":3148},[3055,11218,3123],{"class":3122},[3055,11220,11221],{"class":3126}," imageFiles",[3055,11223,3130],{"class":3069},[3055,11225,8549],{"class":3126},[3055,11227,3080],{"class":3069},[3055,11229,8554],{"class":3168},[3055,11231,3172],{"class":3069},[3055,11233,11234],{"class":3302},"@\"C:\\Images\"",[3055,11236,2971],{"class":3069},[3055,11238,11239],{"class":3302},"\"*.jpg\"",[3055,11241,3324],{"class":3069},[3055,11243,11244,11246,11249,11251,11253,11255,11257,11259],{"class":3057,"line":3153},[3055,11245,3123],{"class":3122},[3055,11247,11248],{"class":3126}," processedImages",[3055,11250,3130],{"class":3069},[3055,11252,3133],{"class":3122},[3055,11254,10542],{"class":3065},[3055,11256,3139],{"class":3069},[3055,11258,3580],{"class":3122},[3055,11260,3145],{"class":3069},[3055,11262,11263],{"class":3057,"line":3160},[3055,11264,3116],{"emptyLinePlaceholder":3115},[3055,11266,11267,11269,11271,11273,11275,11277,11279,11282,11284,11286,11288,11291],{"class":3057,"line":3192},[3055,11268,3292],{"class":3126},[3055,11270,3080],{"class":3069},[3055,11272,3297],{"class":3168},[3055,11274,3172],{"class":3069},[3055,11276,8583],{"class":3302},[3055,11278,3307],{"class":3306},[3055,11280,11281],{"class":3126},"imageFiles",[3055,11283,3080],{"class":3306},[3055,11285,3409],{"class":3126},[3055,11287,3318],{"class":3306},[3055,11289,11290],{"class":3302}," images...\"",[3055,11292,3324],{"class":3069},[3055,11294,11295],{"class":3057,"line":3198},[3055,11296,3116],{"emptyLinePlaceholder":3115},[3055,11298,11299,11301,11303,11305,11307,11309,11311,11314],{"class":3057,"line":3235},[3055,11300,3163],{"class":3126},[3055,11302,3080],{"class":3069},[3055,11304,8665],{"class":3168},[3055,11306,3172],{"class":3069},[3055,11308,11281],{"class":3126},[3055,11310,2971],{"class":3069},[3055,11312,11313],{"class":3126},"imageFile",[3055,11315,3189],{"class":3069},[3055,11317,11318],{"class":3057,"line":3241},[3055,11319,3195],{"class":3069},[3055,11321,11322],{"class":3057,"line":3272},[3055,11323,11324],{"class":3156},"    // Симуляція обробки зображення\n",[3055,11326,11327,11329,11332,11334,11336,11338,11340,11342,11344],{"class":3057,"line":3278},[3055,11328,5881],{"class":3122},[3055,11330,11331],{"class":3126}," fileName",[3055,11333,3130],{"class":3069},[3055,11335,8714],{"class":3126},[3055,11337,3080],{"class":3069},[3055,11339,8719],{"class":3168},[3055,11341,3172],{"class":3069},[3055,11343,11313],{"class":3126},[3055,11345,3324],{"class":3069},[3055,11347,11348,11350,11352,11354,11356,11358,11360,11363,11365,11368,11370,11373,11375,11378,11380,11383,11385,11387],{"class":3057,"line":3284},[3055,11349,3763],{"class":3126},[3055,11351,3080],{"class":3069},[3055,11353,3297],{"class":3168},[3055,11355,3172],{"class":3069},[3055,11357,7740],{"class":3302},[3055,11359,3307],{"class":3306},[3055,11361,11362],{"class":3126},"Thread",[3055,11364,3080],{"class":3306},[3055,11366,11367],{"class":3126},"CurrentThread",[3055,11369,3080],{"class":3306},[3055,11371,11372],{"class":3126},"ManagedThreadId",[3055,11374,3318],{"class":3306},[3055,11376,11377],{"class":3302},"] Processing: ",[3055,11379,3307],{"class":3306},[3055,11381,11382],{"class":3126},"fileName",[3055,11384,3318],{"class":3306},[3055,11386,3321],{"class":3302},[3055,11388,3324],{"class":3069},[3055,11390,11391],{"class":3057,"line":3289},[3055,11392,3116],{"emptyLinePlaceholder":3115},[3055,11394,11395,11398,11400,11402,11404,11406,11408,11410,11412,11414,11416,11418,11420,11422,11424],{"class":3057,"line":3327},[3055,11396,11397],{"class":3126},"    Thread",[3055,11399,3080],{"class":3069},[3055,11401,7770],{"class":3168},[3055,11403,3172],{"class":3069},[3055,11405,9706],{"class":3126},[3055,11407,3080],{"class":3069},[3055,11409,9711],{"class":3126},[3055,11411,3080],{"class":3069},[3055,11413,9716],{"class":3168},[3055,11415,3172],{"class":3069},[3055,11417,5295],{"class":3175},[3055,11419,2971],{"class":3069},[3055,11421,9725],{"class":3175},[3055,11423,9871],{"class":3069},[3055,11425,11426],{"class":3156},"// Симуляція роботи\n",[3055,11428,11429],{"class":3057,"line":3333},[3055,11430,3116],{"emptyLinePlaceholder":3115},[3055,11432,11433],{"class":3057,"line":3338},[3055,11434,11435],{"class":3156},"    // Додаємо результат у ConcurrentBag (lock-free для цього потоку!)\n",[3055,11437,11438,11441,11443,11445,11447,11450,11452,11454,11456,11458],{"class":3057,"line":3755},[3055,11439,11440],{"class":3126},"    processedImages",[3055,11442,3080],{"class":3069},[3055,11444,3249],{"class":3168},[3055,11446,3172],{"class":3069},[3055,11448,11449],{"class":3302},"$\"processed_",[3055,11451,3307],{"class":3306},[3055,11453,11382],{"class":3126},[3055,11455,3318],{"class":3306},[3055,11457,3321],{"class":3302},[3055,11459,3324],{"class":3069},[3055,11461,11462],{"class":3057,"line":3760},[3055,11463,3281],{"class":3069},[3055,11465,11466],{"class":3057,"line":3797},[3055,11467,3116],{"emptyLinePlaceholder":3115},[3055,11469,11470,11472,11474,11476,11478,11480,11482,11485,11487,11490,11492,11494,11496,11499],{"class":3057,"line":3826},[3055,11471,3292],{"class":3126},[3055,11473,3080],{"class":3069},[3055,11475,3297],{"class":3168},[3055,11477,3172],{"class":3069},[3055,11479,5988],{"class":3302},[3055,11481,8094],{"class":8093},[3055,11483,11484],{"class":3302},"Processed ",[3055,11486,3307],{"class":3306},[3055,11488,11489],{"class":3126},"processedImages",[3055,11491,3080],{"class":3306},[3055,11493,3315],{"class":3126},[3055,11495,3318],{"class":3306},[3055,11497,11498],{"class":3302}," images\"",[3055,11500,3324],{"class":3069},[3055,11502,11503],{"class":3057,"line":3831},[3055,11504,3116],{"emptyLinePlaceholder":3115},[3055,11506,11507],{"class":3057,"line":3836},[3055,11508,11509],{"class":3156},"// Забираємо всі результати (тут може бути \"крадіжка\", але це одноразова операція)\n",[3055,11511,11512,11514,11517,11519,11521,11523,11526],{"class":3057,"line":3842},[3055,11513,3123],{"class":3122},[3055,11515,11516],{"class":3126}," results",[3055,11518,3130],{"class":3069},[3055,11520,11489],{"class":3126},[3055,11522,3080],{"class":3069},[3055,11524,11525],{"class":3168},"ToArray",[3055,11527,4071],{"class":3069},[3055,11529,11530,11532,11534,11536,11538,11540,11542,11544,11546,11548,11551],{"class":3057,"line":3848},[3055,11531,5957],{"class":3061},[3055,11533,3204],{"class":3069},[3055,11535,3123],{"class":3122},[3055,11537,9255],{"class":3126},[3055,11539,5967],{"class":3061},[3055,11541,11516],{"class":3126},[3055,11543,3080],{"class":3069},[3055,11545,8354],{"class":3168},[3055,11547,3172],{"class":3069},[3055,11549,11550],{"class":3175},"5",[3055,11552,4915],{"class":3069},[3055,11554,11555],{"class":3057,"line":3854},[3055,11556,3195],{"class":3069},[3055,11558,11559,11561,11563,11565,11567,11570,11572,11574,11576,11578],{"class":3057,"line":4603},[3055,11560,3763],{"class":3126},[3055,11562,3080],{"class":3069},[3055,11564,3297],{"class":3168},[3055,11566,3172],{"class":3069},[3055,11568,11569],{"class":3302},"$\"  - ",[3055,11571,3307],{"class":3306},[3055,11573,9279],{"class":3126},[3055,11575,3318],{"class":3306},[3055,11577,3321],{"class":3302},[3055,11579,3324],{"class":3069},[3055,11581,11582],{"class":3057,"line":4609},[3055,11583,3484],{"class":3069},[3025,11585],{},[3032,11587,11589],{"id":11588},"коли-використовувати","Коли Використовувати",[3044,11591,11594],{"className":3046,"code":11592,"filename":11593,"language":3049,"meta":3050,"style":3051},"using System.Collections.Concurrent;\nusing System.Threading.Tasks;\n\n// ✅ ДОБРЕ: Parallel.ForEach з локальною обробкою\nvar bag = new ConcurrentBag\u003Cstring>();\n\nParallel.ForEach(Directory.GetFiles(@\"C:\\Logs\"), file =>\n{\n    // Кожен потік обробляє свої файли і додає результати\n    var lines = File.ReadAllLines(file);\n    foreach (var line in lines)\n    {\n        if (line.Contains(\"ERROR\"))\n        {\n            bag.Add(line);  // Додає у локальний список цього потоку\n        }\n    }\n});\n\n// Після завершення — забираємо всі результати\nvar errors = bag.ToArray();\nConsole.WriteLine($\"Found {errors.Length} errors\");\n","ConcurrentBagUseCase.cs",[2968,11595,11596,11612,11628,11632,11637,11656,11660,11687,11691,11696,11719,11737,11741,11761,11765,11783,11787,11791,11795,11799,11804,11821],{"__ignoreMap":3051},[3055,11597,11598,11600,11602,11604,11606,11608,11610],{"class":3057,"line":3058},[3055,11599,3062],{"class":3061},[3055,11601,3066],{"class":3065},[3055,11603,3080],{"class":3069},[3055,11605,3083],{"class":3065},[3055,11607,3080],{"class":3069},[3055,11609,6738],{"class":3065},[3055,11611,3070],{"class":3069},[3055,11613,11614,11616,11618,11620,11622,11624,11626],{"class":3057,"line":3073},[3055,11615,3062],{"class":3061},[3055,11617,3066],{"class":3065},[3055,11619,3080],{"class":3069},[3055,11621,3102],{"class":3065},[3055,11623,3080],{"class":3069},[3055,11625,3107],{"class":3065},[3055,11627,3070],{"class":3069},[3055,11629,11630],{"class":3057,"line":3093},[3055,11631,3116],{"emptyLinePlaceholder":3115},[3055,11633,11634],{"class":3057,"line":3112},[3055,11635,11636],{"class":3156},"// ✅ ДОБРЕ: Parallel.ForEach з локальною обробкою\n",[3055,11638,11639,11641,11644,11646,11648,11650,11652,11654],{"class":3057,"line":3119},[3055,11640,3123],{"class":3122},[3055,11642,11643],{"class":3126}," bag",[3055,11645,3130],{"class":3069},[3055,11647,3133],{"class":3122},[3055,11649,10542],{"class":3065},[3055,11651,3139],{"class":3069},[3055,11653,3580],{"class":3122},[3055,11655,3145],{"class":3069},[3055,11657,11658],{"class":3057,"line":3148},[3055,11659,3116],{"emptyLinePlaceholder":3115},[3055,11661,11662,11664,11666,11668,11670,11672,11674,11676,11678,11680,11683,11685],{"class":3057,"line":3153},[3055,11663,3163],{"class":3126},[3055,11665,3080],{"class":3069},[3055,11667,8665],{"class":3168},[3055,11669,3172],{"class":3069},[3055,11671,8549],{"class":3126},[3055,11673,3080],{"class":3069},[3055,11675,8554],{"class":3168},[3055,11677,3172],{"class":3069},[3055,11679,8559],{"class":3302},[3055,11681,11682],{"class":3069},"), ",[3055,11684,8674],{"class":3126},[3055,11686,3189],{"class":3069},[3055,11688,11689],{"class":3057,"line":3160},[3055,11690,3195],{"class":3069},[3055,11692,11693],{"class":3057,"line":3192},[3055,11694,11695],{"class":3156},"    // Кожен потік обробляє свої файли і додає результати\n",[3055,11697,11698,11701,11704,11706,11708,11710,11713,11715,11717],{"class":3057,"line":3198},[3055,11699,11700],{"class":3122},"    var",[3055,11702,11703],{"class":3126}," lines",[3055,11705,3130],{"class":3069},[3055,11707,8043],{"class":3126},[3055,11709,3080],{"class":3069},[3055,11711,11712],{"class":3168},"ReadAllLines",[3055,11714,3172],{"class":3069},[3055,11716,8674],{"class":3126},[3055,11718,3324],{"class":3069},[3055,11720,11721,11724,11726,11728,11731,11733,11735],{"class":3057,"line":3235},[3055,11722,11723],{"class":3061},"    foreach",[3055,11725,3204],{"class":3069},[3055,11727,3123],{"class":3122},[3055,11729,11730],{"class":3126}," line",[3055,11732,5967],{"class":3061},[3055,11734,11703],{"class":3126},[3055,11736,3384],{"class":3069},[3055,11738,11739],{"class":3057,"line":3241},[3055,11740,3238],{"class":3069},[3055,11742,11743,11745,11747,11749,11751,11754,11756,11759],{"class":3057,"line":3272},[3055,11744,6369],{"class":3061},[3055,11746,3204],{"class":3069},[3055,11748,3057],{"class":3126},[3055,11750,3080],{"class":3069},[3055,11752,11753],{"class":3168},"Contains",[3055,11755,3172],{"class":3069},[3055,11757,11758],{"class":3302},"\"ERROR\"",[3055,11760,4915],{"class":3069},[3055,11762,11763],{"class":3057,"line":3278},[3055,11764,3665],{"class":3069},[3055,11766,11767,11770,11772,11774,11776,11778,11780],{"class":3057,"line":3284},[3055,11768,11769],{"class":3126},"            bag",[3055,11771,3080],{"class":3069},[3055,11773,3249],{"class":3168},[3055,11775,3172],{"class":3069},[3055,11777,3057],{"class":3126},[3055,11779,3266],{"class":3069},[3055,11781,11782],{"class":3156},"// Додає у локальний список цього потоку\n",[3055,11784,11785],{"class":3057,"line":3289},[3055,11786,3728],{"class":3069},[3055,11788,11789],{"class":3057,"line":3327},[3055,11790,3275],{"class":3069},[3055,11792,11793],{"class":3057,"line":3333},[3055,11794,3281],{"class":3069},[3055,11796,11797],{"class":3057,"line":3338},[3055,11798,3116],{"emptyLinePlaceholder":3115},[3055,11800,11801],{"class":3057,"line":3755},[3055,11802,11803],{"class":3156},"// Після завершення — забираємо всі результати\n",[3055,11805,11806,11808,11811,11813,11815,11817,11819],{"class":3057,"line":3760},[3055,11807,3123],{"class":3122},[3055,11809,11810],{"class":3126}," errors",[3055,11812,3130],{"class":3069},[3055,11814,10636],{"class":3126},[3055,11816,3080],{"class":3069},[3055,11818,11525],{"class":3168},[3055,11820,4071],{"class":3069},[3055,11822,11823,11825,11827,11829,11831,11834,11836,11839,11841,11843,11845,11848],{"class":3057,"line":3797},[3055,11824,3292],{"class":3126},[3055,11826,3080],{"class":3069},[3055,11828,3297],{"class":3168},[3055,11830,3172],{"class":3069},[3055,11832,11833],{"class":3302},"$\"Found ",[3055,11835,3307],{"class":3306},[3055,11837,11838],{"class":3126},"errors",[3055,11840,3080],{"class":3306},[3055,11842,3409],{"class":3126},[3055,11844,3318],{"class":3306},[3055,11846,11847],{"class":3302}," errors\"",[3055,11849,3324],{"class":3069},[3025,11851],{},[2959,11853,11143,11855],{"id":11854},"blockingcollection-bounded-producer-consumer",[3037,11856,11857],{}," — Bounded Producer-Consumer",[3032,11859,11861],{"id":11860},"концепція-blocking-queue-з-обмеженням","Концепція: Blocking Queue з Обмеженням",[2964,11863,11864,11867,11868,11871,11872,11874],{},[2968,11865,11866],{},"BlockingCollection\u003CT>"," — обгортка над будь-якою ",[2968,11869,11870],{},"IProducerConsumerCollection\u003CT>"," (зазвичай ",[2968,11873,9070],{},") що додає:",[3009,11876,11877,11883,11895],{},[3012,11878,11879,11882],{},[2977,11880,11881],{},"Bounded capacity"," — обмеження розміру черги",[3012,11884,11885,2980,11888,11890,11891,11894],{},[2977,11886,11887],{},"Blocking operations",[2968,11889,11037],{}," блокується якщо черга повна, ",[2968,11892,11893],{},"Take()"," блокується якщо порожня",[3012,11896,11897,11900],{},[2977,11898,11899],{},"CompleteAdding"," — сигнал що більше не буде елементів",[3044,11902,11905],{"className":11903,"code":11904,"language":3496},[3494],"Producer                BlockingCollection           Consumer\n────────────────────────────────────────────────────────────────\nAdd(item1) ────────▶  [item1]\nAdd(item2) ────────▶  [item1, item2]\n                                        ◀──────── Take() = item1\nAdd(item3) ────────▶  [item2, item3]\nAdd(item4) ────────▶  [item2, item3, item4]\nAdd(item5) ────────▶  [item2, item3, item4, item5]  ← Черга повна (capacity = 4)\nAdd(item6) ────────▶  БЛОКУЄТЬСЯ! Чекає поки Consumer забере елемент\n                                        ◀──────── Take() = item2\nAdd(item6) ────────▶  [item3, item4, item5, item6]  ← Тепер успішно\nCompleteAdding() ──▶  [item3, item4, item5, item6]  ← Сигнал \"більше не буде\"\n                                        ◀──────── Take() = item3\n                                        ◀──────── Take() = item4\n                                        ◀──────── Take() = item5\n                                        ◀──────── Take() = item6\n                                        ◀──────── Take() → InvalidOperationException\n                                                          (черга порожня + CompleteAdding)\n",[2968,11906,11904],{"__ignoreMap":3051},[3032,11908,4622],{"id":11909},"основні-методи-3",[3044,11911,11914],{"className":3046,"code":11912,"filename":11913,"language":3049,"meta":3050,"style":3051},"using System.Collections.Concurrent;\n\n// Створення з обмеженням capacity = 10\nvar collection = new BlockingCollection\u003Cint>(boundedCapacity: 10);\n\n// Add — додати елемент (блокується якщо повна)\ncollection.Add(1);\ncollection.Add(2);\n\n// TryAdd — спроба додати з timeout\nbool added = collection.TryAdd(3, TimeSpan.FromSeconds(1));\nConsole.WriteLine($\"Added: {added}\");\n\n// Take — забрати елемент (блокується якщо порожня)\nint item = collection.Take();\nConsole.WriteLine($\"Taken: {item}\");  // 1\n\n// TryTake — спроба забрати з timeout\nif (collection.TryTake(out int result, TimeSpan.FromSeconds(1)))\n{\n    Console.WriteLine($\"Taken: {result}\");  // 2\n}\n\n// CompleteAdding — сигнал що більше не буде елементів\ncollection.CompleteAdding();\n\n// IsCompleted — перевірка чи завершено додавання та черга порожня\nConsole.WriteLine($\"IsCompleted: {collection.IsCompleted}\");\n\n// IsAddingCompleted — перевірка чи викликано CompleteAdding\nConsole.WriteLine($\"IsAddingCompleted: {collection.IsAddingCompleted}\");\n","BlockingCollectionBasics.cs",[2968,11915,11916,11932,11936,11941,11970,11974,11979,11994,12008,12012,12017,12049,12071,12075,12080,12096,12122,12126,12131,12166,12170,12194,12198,12202,12207,12217,12221,12226,12254,12258,12263],{"__ignoreMap":3051},[3055,11917,11918,11920,11922,11924,11926,11928,11930],{"class":3057,"line":3058},[3055,11919,3062],{"class":3061},[3055,11921,3066],{"class":3065},[3055,11923,3080],{"class":3069},[3055,11925,3083],{"class":3065},[3055,11927,3080],{"class":3069},[3055,11929,6738],{"class":3065},[3055,11931,3070],{"class":3069},[3055,11933,11934],{"class":3057,"line":3073},[3055,11935,3116],{"emptyLinePlaceholder":3115},[3055,11937,11938],{"class":3057,"line":3093},[3055,11939,11940],{"class":3156},"// Створення з обмеженням capacity = 10\n",[3055,11942,11943,11945,11948,11950,11952,11955,11957,11959,11961,11964,11966,11968],{"class":3057,"line":3112},[3055,11944,3123],{"class":3122},[3055,11946,11947],{"class":3126}," collection",[3055,11949,3130],{"class":3069},[3055,11951,3133],{"class":3122},[3055,11953,11954],{"class":3065}," BlockingCollection",[3055,11956,3139],{"class":3069},[3055,11958,3142],{"class":3122},[3055,11960,7609],{"class":3069},[3055,11962,11963],{"class":3126},"boundedCapacity",[3055,11965,5292],{"class":3069},[3055,11967,3181],{"class":3175},[3055,11969,3324],{"class":3069},[3055,11971,11972],{"class":3057,"line":3119},[3055,11973,3116],{"emptyLinePlaceholder":3115},[3055,11975,11976],{"class":3057,"line":3148},[3055,11977,11978],{"class":3156},"// Add — додати елемент (блокується якщо повна)\n",[3055,11980,11981,11984,11986,11988,11990,11992],{"class":3057,"line":3153},[3055,11982,11983],{"class":3126},"collection",[3055,11985,3080],{"class":3069},[3055,11987,3249],{"class":3168},[3055,11989,3172],{"class":3069},[3055,11991,3433],{"class":3175},[3055,11993,3324],{"class":3069},[3055,11995,11996,11998,12000,12002,12004,12006],{"class":3057,"line":3160},[3055,11997,11983],{"class":3126},[3055,11999,3080],{"class":3069},[3055,12001,3249],{"class":3168},[3055,12003,3172],{"class":3069},[3055,12005,5278],{"class":3175},[3055,12007,3324],{"class":3069},[3055,12009,12010],{"class":3057,"line":3192},[3055,12011,3116],{"emptyLinePlaceholder":3115},[3055,12013,12014],{"class":3057,"line":3198},[3055,12015,12016],{"class":3156},"// TryAdd — спроба додати з timeout\n",[3055,12018,12019,12021,12023,12025,12027,12029,12031,12033,12035,12037,12039,12041,12043,12045,12047],{"class":3057,"line":3235},[3055,12020,4670],{"class":3122},[3055,12022,4673],{"class":3126},[3055,12024,3130],{"class":3069},[3055,12026,11983],{"class":3126},[3055,12028,3080],{"class":3069},[3055,12030,4683],{"class":3168},[3055,12032,3172],{"class":3069},[3055,12034,9223],{"class":3175},[3055,12036,2971],{"class":3069},[3055,12038,6885],{"class":3126},[3055,12040,3080],{"class":3069},[3055,12042,7616],{"class":3168},[3055,12044,3172],{"class":3069},[3055,12046,3433],{"class":3175},[3055,12048,7623],{"class":3069},[3055,12050,12051,12053,12055,12057,12059,12061,12063,12065,12067,12069],{"class":3057,"line":3241},[3055,12052,3292],{"class":3126},[3055,12054,3080],{"class":3069},[3055,12056,3297],{"class":3168},[3055,12058,3172],{"class":3069},[3055,12060,4708],{"class":3302},[3055,12062,3307],{"class":3306},[3055,12064,4713],{"class":3126},[3055,12066,3318],{"class":3306},[3055,12068,3321],{"class":3302},[3055,12070,3324],{"class":3069},[3055,12072,12073],{"class":3057,"line":3272},[3055,12074,3116],{"emptyLinePlaceholder":3115},[3055,12076,12077],{"class":3057,"line":3278},[3055,12078,12079],{"class":3156},"// Take — забрати елемент (блокується якщо порожня)\n",[3055,12081,12082,12084,12086,12088,12090,12092,12094],{"class":3057,"line":3284},[3055,12083,3142],{"class":3122},[3055,12085,3381],{"class":3126},[3055,12087,3130],{"class":3069},[3055,12089,11983],{"class":3126},[3055,12091,3080],{"class":3069},[3055,12093,8354],{"class":3168},[3055,12095,4071],{"class":3069},[3055,12097,12098,12100,12102,12104,12106,12109,12111,12113,12115,12117,12119],{"class":3057,"line":3289},[3055,12099,3292],{"class":3126},[3055,12101,3080],{"class":3069},[3055,12103,3297],{"class":3168},[3055,12105,3172],{"class":3069},[3055,12107,12108],{"class":3302},"$\"Taken: ",[3055,12110,3307],{"class":3306},[3055,12112,3462],{"class":3126},[3055,12114,3318],{"class":3306},[3055,12116,3321],{"class":3302},[3055,12118,3266],{"class":3069},[3055,12120,12121],{"class":3156},"// 1\n",[3055,12123,12124],{"class":3057,"line":3327},[3055,12125,3116],{"emptyLinePlaceholder":3115},[3055,12127,12128],{"class":3057,"line":3333},[3055,12129,12130],{"class":3156},"// TryTake — спроба забрати з timeout\n",[3055,12132,12133,12135,12137,12139,12141,12143,12145,12147,12149,12151,12153,12155,12157,12159,12161,12163],{"class":3057,"line":3338},[3055,12134,4888],{"class":3061},[3055,12136,3204],{"class":3069},[3055,12138,11983],{"class":3126},[3055,12140,3080],{"class":3069},[3055,12142,10699],{"class":3168},[3055,12144,3172],{"class":3069},[3055,12146,4906],{"class":3122},[3055,12148,4909],{"class":3122},[3055,12150,9255],{"class":3126},[3055,12152,2971],{"class":3069},[3055,12154,6885],{"class":3126},[3055,12156,3080],{"class":3069},[3055,12158,7616],{"class":3168},[3055,12160,3172],{"class":3069},[3055,12162,3433],{"class":3175},[3055,12164,12165],{"class":3069},")))\n",[3055,12167,12168],{"class":3057,"line":3755},[3055,12169,3195],{"class":3069},[3055,12171,12172,12174,12176,12178,12180,12182,12184,12186,12188,12190,12192],{"class":3057,"line":3760},[3055,12173,3763],{"class":3126},[3055,12175,3080],{"class":3069},[3055,12177,3297],{"class":3168},[3055,12179,3172],{"class":3069},[3055,12181,12108],{"class":3302},[3055,12183,3307],{"class":3306},[3055,12185,9279],{"class":3126},[3055,12187,3318],{"class":3306},[3055,12189,3321],{"class":3302},[3055,12191,3266],{"class":3069},[3055,12193,9356],{"class":3156},[3055,12195,12196],{"class":3057,"line":3797},[3055,12197,3484],{"class":3069},[3055,12199,12200],{"class":3057,"line":3826},[3055,12201,3116],{"emptyLinePlaceholder":3115},[3055,12203,12204],{"class":3057,"line":3831},[3055,12205,12206],{"class":3156},"// CompleteAdding — сигнал що більше не буде елементів\n",[3055,12208,12209,12211,12213,12215],{"class":3057,"line":3836},[3055,12210,11983],{"class":3126},[3055,12212,3080],{"class":3069},[3055,12214,11899],{"class":3168},[3055,12216,4071],{"class":3069},[3055,12218,12219],{"class":3057,"line":3842},[3055,12220,3116],{"emptyLinePlaceholder":3115},[3055,12222,12223],{"class":3057,"line":3848},[3055,12224,12225],{"class":3156},"// IsCompleted — перевірка чи завершено додавання та черга порожня\n",[3055,12227,12228,12230,12232,12234,12236,12239,12241,12243,12245,12248,12250,12252],{"class":3057,"line":3854},[3055,12229,3292],{"class":3126},[3055,12231,3080],{"class":3069},[3055,12233,3297],{"class":3168},[3055,12235,3172],{"class":3069},[3055,12237,12238],{"class":3302},"$\"IsCompleted: ",[3055,12240,3307],{"class":3306},[3055,12242,11983],{"class":3126},[3055,12244,3080],{"class":3306},[3055,12246,12247],{"class":3126},"IsCompleted",[3055,12249,3318],{"class":3306},[3055,12251,3321],{"class":3302},[3055,12253,3324],{"class":3069},[3055,12255,12256],{"class":3057,"line":4603},[3055,12257,3116],{"emptyLinePlaceholder":3115},[3055,12259,12260],{"class":3057,"line":4609},[3055,12261,12262],{"class":3156},"// IsAddingCompleted — перевірка чи викликано CompleteAdding\n",[3055,12264,12265,12267,12269,12271,12273,12276,12278,12280,12282,12285,12287,12289],{"class":3057,"line":7082},[3055,12266,3292],{"class":3126},[3055,12268,3080],{"class":3069},[3055,12270,3297],{"class":3168},[3055,12272,3172],{"class":3069},[3055,12274,12275],{"class":3302},"$\"IsAddingCompleted: ",[3055,12277,3307],{"class":3306},[3055,12279,11983],{"class":3126},[3055,12281,3080],{"class":3306},[3055,12283,12284],{"class":3126},"IsAddingCompleted",[3055,12286,3318],{"class":3306},[3055,12288,3321],{"class":3302},[3055,12290,3324],{"class":3069},[3032,12292,12294],{"id":12293},"getconsumingenumerable-ідіоматичний-consumer-pattern","GetConsumingEnumerable — Ідіоматичний Consumer Pattern",[2964,12296,12297,12300],{},[2968,12298,12299],{},"GetConsumingEnumerable()"," — найзручніший спосіб обробляти елементи у consumer потоці. Він автоматично:",[3009,12302,12303,12306,12313],{},[3012,12304,12305],{},"Блокується поки чекає нові елементи",[3012,12307,12308,12309,12312],{},"Завершується коли викликано ",[2968,12310,12311],{},"CompleteAdding()"," та черга порожня",[3012,12314,12315],{},"Видаляє елементи з колекції під час ітерації",[3044,12317,12320],{"className":3046,"code":12318,"filename":12319,"language":3049,"meta":3050,"style":3051},"using System;\nusing System.Collections.Concurrent;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nvar collection = new BlockingCollection\u003Cstring>(boundedCapacity: 5);\n\n// Producer: додає повідомлення\nvar producer = Task.Run(() =>\n{\n    for (int i = 0; i \u003C 10; i++)\n    {\n        string message = $\"Message-{i}\";\n        collection.Add(message);\n        Console.WriteLine($\"[Producer] Added: {message}\");\n        Thread.Sleep(100);\n    }\n\n    collection.CompleteAdding();  // Сигнал що більше не буде\n    Console.WriteLine(\"[Producer] Completed adding\");\n});\n\n// Consumer: обробляє повідомлення\nvar consumer = Task.Run(() =>\n{\n    // GetConsumingEnumerable блокується поки чекає елементи\n    // та автоматично завершується після CompleteAdding\n    foreach (string message in collection.GetConsumingEnumerable())\n    {\n        Console.WriteLine($\"[Consumer] Processing: {message}\");\n        Thread.Sleep(150);  // Симуляція обробки\n    }\n\n    Console.WriteLine(\"[Consumer] No more items\");\n});\n\nawait Task.WhenAll(producer, consumer);\nConsole.WriteLine(\"Done!\");\n","GetConsumingEnumerable.cs",[2968,12321,12322,12330,12346,12358,12374,12378,12404,12408,12413,12429,12433,12461,12465,12485,12500,12523,12537,12541,12545,12559,12574,12578,12582,12586,12602,12606,12611,12616,12638,12642,12664,12680,12684,12688,12703,12707,12711,12731],{"__ignoreMap":3051},[3055,12323,12324,12326,12328],{"class":3057,"line":3058},[3055,12325,3062],{"class":3061},[3055,12327,3066],{"class":3065},[3055,12329,3070],{"class":3069},[3055,12331,12332,12334,12336,12338,12340,12342,12344],{"class":3057,"line":3073},[3055,12333,3062],{"class":3061},[3055,12335,3066],{"class":3065},[3055,12337,3080],{"class":3069},[3055,12339,3083],{"class":3065},[3055,12341,3080],{"class":3069},[3055,12343,6738],{"class":3065},[3055,12345,3070],{"class":3069},[3055,12347,12348,12350,12352,12354,12356],{"class":3057,"line":3093},[3055,12349,3062],{"class":3061},[3055,12351,3066],{"class":3065},[3055,12353,3080],{"class":3069},[3055,12355,3102],{"class":3065},[3055,12357,3070],{"class":3069},[3055,12359,12360,12362,12364,12366,12368,12370,12372],{"class":3057,"line":3112},[3055,12361,3062],{"class":3061},[3055,12363,3066],{"class":3065},[3055,12365,3080],{"class":3069},[3055,12367,3102],{"class":3065},[3055,12369,3080],{"class":3069},[3055,12371,3107],{"class":3065},[3055,12373,3070],{"class":3069},[3055,12375,12376],{"class":3057,"line":3119},[3055,12377,3116],{"emptyLinePlaceholder":3115},[3055,12379,12380,12382,12384,12386,12388,12390,12392,12394,12396,12398,12400,12402],{"class":3057,"line":3148},[3055,12381,3123],{"class":3122},[3055,12383,11947],{"class":3126},[3055,12385,3130],{"class":3069},[3055,12387,3133],{"class":3122},[3055,12389,11954],{"class":3065},[3055,12391,3139],{"class":3069},[3055,12393,3580],{"class":3122},[3055,12395,7609],{"class":3069},[3055,12397,11963],{"class":3126},[3055,12399,5292],{"class":3069},[3055,12401,11550],{"class":3175},[3055,12403,3324],{"class":3069},[3055,12405,12406],{"class":3057,"line":3153},[3055,12407,3116],{"emptyLinePlaceholder":3115},[3055,12409,12410],{"class":3057,"line":3160},[3055,12411,12412],{"class":3156},"// Producer: додає повідомлення\n",[3055,12414,12415,12417,12419,12421,12423,12425,12427],{"class":3057,"line":3192},[3055,12416,3123],{"class":3122},[3055,12418,9573],{"class":3126},[3055,12420,3130],{"class":3069},[3055,12422,9578],{"class":3126},[3055,12424,3080],{"class":3069},[3055,12426,9583],{"class":3168},[3055,12428,9586],{"class":3069},[3055,12430,12431],{"class":3057,"line":3198},[3055,12432,3195],{"class":3069},[3055,12434,12435,12437,12439,12441,12443,12445,12447,12449,12451,12453,12455,12457,12459],{"class":3057,"line":3235},[3055,12436,3201],{"class":3061},[3055,12438,3204],{"class":3069},[3055,12440,3142],{"class":3122},[3055,12442,5444],{"class":3126},[3055,12444,3130],{"class":3069},[3055,12446,3176],{"class":3175},[3055,12448,3216],{"class":3069},[3055,12450,3186],{"class":3126},[3055,12452,3222],{"class":3069},[3055,12454,3181],{"class":3175},[3055,12456,3216],{"class":3069},[3055,12458,3186],{"class":3126},[3055,12460,3232],{"class":3069},[3055,12462,12463],{"class":3057,"line":3241},[3055,12464,3238],{"class":3069},[3055,12466,12467,12469,12471,12473,12475,12477,12479,12481,12483],{"class":3057,"line":3272},[3055,12468,4143],{"class":3122},[3055,12470,9635],{"class":3126},[3055,12472,3130],{"class":3069},[3055,12474,9640],{"class":3302},[3055,12476,3307],{"class":3306},[3055,12478,3186],{"class":3126},[3055,12480,3318],{"class":3306},[3055,12482,3321],{"class":3302},[3055,12484,3070],{"class":3069},[3055,12486,12487,12490,12492,12494,12496,12498],{"class":3057,"line":3278},[3055,12488,12489],{"class":3126},"        collection",[3055,12491,3080],{"class":3069},[3055,12493,3249],{"class":3168},[3055,12495,3172],{"class":3069},[3055,12497,9668],{"class":3126},[3055,12499,3324],{"class":3069},[3055,12501,12502,12504,12506,12508,12510,12513,12515,12517,12519,12521],{"class":3057,"line":3284},[3055,12503,5416],{"class":3126},[3055,12505,3080],{"class":3069},[3055,12507,3297],{"class":3168},[3055,12509,3172],{"class":3069},[3055,12511,12512],{"class":3302},"$\"[Producer] Added: ",[3055,12514,3307],{"class":3306},[3055,12516,9668],{"class":3126},[3055,12518,3318],{"class":3306},[3055,12520,3321],{"class":3302},[3055,12522,3324],{"class":3069},[3055,12524,12525,12527,12529,12531,12533,12535],{"class":3057,"line":3289},[3055,12526,7765],{"class":3126},[3055,12528,3080],{"class":3069},[3055,12530,7770],{"class":3168},[3055,12532,3172],{"class":3069},[3055,12534,4693],{"class":3175},[3055,12536,3324],{"class":3069},[3055,12538,12539],{"class":3057,"line":3327},[3055,12540,3275],{"class":3069},[3055,12542,12543],{"class":3057,"line":3333},[3055,12544,3116],{"emptyLinePlaceholder":3115},[3055,12546,12547,12550,12552,12554,12556],{"class":3057,"line":3338},[3055,12548,12549],{"class":3126},"    collection",[3055,12551,3080],{"class":3069},[3055,12553,11899],{"class":3168},[3055,12555,5215],{"class":3069},[3055,12557,12558],{"class":3156},"// Сигнал що більше не буде\n",[3055,12560,12561,12563,12565,12567,12569,12572],{"class":3057,"line":3755},[3055,12562,3763],{"class":3126},[3055,12564,3080],{"class":3069},[3055,12566,3297],{"class":3168},[3055,12568,3172],{"class":3069},[3055,12570,12571],{"class":3302},"\"[Producer] Completed adding\"",[3055,12573,3324],{"class":3069},[3055,12575,12576],{"class":3057,"line":3760},[3055,12577,3281],{"class":3069},[3055,12579,12580],{"class":3057,"line":3797},[3055,12581,3116],{"emptyLinePlaceholder":3115},[3055,12583,12584],{"class":3057,"line":3826},[3055,12585,9744],{"class":3156},[3055,12587,12588,12590,12592,12594,12596,12598,12600],{"class":3057,"line":3831},[3055,12589,3123],{"class":3122},[3055,12591,9751],{"class":3126},[3055,12593,3130],{"class":3069},[3055,12595,9578],{"class":3126},[3055,12597,3080],{"class":3069},[3055,12599,9583],{"class":3168},[3055,12601,9586],{"class":3069},[3055,12603,12604],{"class":3057,"line":3836},[3055,12605,3195],{"class":3069},[3055,12607,12608],{"class":3057,"line":3842},[3055,12609,12610],{"class":3156},"    // GetConsumingEnumerable блокується поки чекає елементи\n",[3055,12612,12613],{"class":3057,"line":3848},[3055,12614,12615],{"class":3156},"    // та автоматично завершується після CompleteAdding\n",[3055,12617,12618,12620,12622,12624,12626,12628,12630,12632,12635],{"class":3057,"line":3854},[3055,12619,11723],{"class":3061},[3055,12621,3204],{"class":3069},[3055,12623,3580],{"class":3122},[3055,12625,9635],{"class":3126},[3055,12627,5967],{"class":3061},[3055,12629,11947],{"class":3126},[3055,12631,3080],{"class":3069},[3055,12633,12634],{"class":3168},"GetConsumingEnumerable",[3055,12636,12637],{"class":3069},"())\n",[3055,12639,12640],{"class":3057,"line":4603},[3055,12641,3238],{"class":3069},[3055,12643,12644,12646,12648,12650,12652,12654,12656,12658,12660,12662],{"class":3057,"line":4609},[3055,12645,5416],{"class":3126},[3055,12647,3080],{"class":3069},[3055,12649,3297],{"class":3168},[3055,12651,3172],{"class":3069},[3055,12653,9829],{"class":3302},[3055,12655,3307],{"class":3306},[3055,12657,9668],{"class":3126},[3055,12659,3318],{"class":3306},[3055,12661,3321],{"class":3302},[3055,12663,3324],{"class":3069},[3055,12665,12666,12668,12670,12672,12674,12676,12678],{"class":3057,"line":7082},[3055,12667,7765],{"class":3126},[3055,12669,3080],{"class":3069},[3055,12671,7770],{"class":3168},[3055,12673,3172],{"class":3069},[3055,12675,9725],{"class":3175},[3055,12677,3266],{"class":3069},[3055,12679,9874],{"class":3156},[3055,12681,12682],{"class":3057,"line":7095},[3055,12683,3275],{"class":3069},[3055,12685,12686],{"class":3057,"line":7104},[3055,12687,3116],{"emptyLinePlaceholder":3115},[3055,12689,12690,12692,12694,12696,12698,12701],{"class":3057,"line":7109},[3055,12691,3763],{"class":3126},[3055,12693,3080],{"class":3069},[3055,12695,3297],{"class":3168},[3055,12697,3172],{"class":3069},[3055,12699,12700],{"class":3302},"\"[Consumer] No more items\"",[3055,12702,3324],{"class":3069},[3055,12704,12705],{"class":3057,"line":7114},[3055,12706,3281],{"class":3069},[3055,12708,12709],{"class":3057,"line":7152},[3055,12710,3116],{"emptyLinePlaceholder":3115},[3055,12712,12713,12715,12717,12719,12721,12723,12725,12727,12729],{"class":3057,"line":7157},[3055,12714,9930],{"class":3122},[3055,12716,9933],{"class":3126},[3055,12718,3080],{"class":3069},[3055,12720,9971],{"class":3168},[3055,12722,3172],{"class":3069},[3055,12724,9976],{"class":3126},[3055,12726,2971],{"class":3069},[3055,12728,9981],{"class":3126},[3055,12730,3324],{"class":3069},[3055,12732,12733,12735,12737,12739,12741,12744],{"class":3057,"line":7187},[3055,12734,3292],{"class":3126},[3055,12736,3080],{"class":3069},[3055,12738,3297],{"class":3168},[3055,12740,3172],{"class":3069},[3055,12742,12743],{"class":3302},"\"Done!\"",[3055,12745,3324],{"class":3069},[3032,12747,12749],{"id":12748},"практичний-приклад-multi-producer-multi-consumer-pipeline","Практичний Приклад: Multi-Producer, Multi-Consumer Pipeline",[3044,12751,12754],{"className":3046,"code":12752,"filename":12753,"language":3049,"meta":3050,"style":3051},"using System;\nusing System.Collections.Concurrent;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nvar collection = new BlockingCollection\u003Cint>(boundedCapacity: 20);\n\n// 3 Producers: генерують числа\nvar producers = Enumerable.Range(0, 3).Select(producerId =>\n    Task.Run(() =>\n    {\n        for (int i = 0; i \u003C 10; i++)\n        {\n            int value = producerId * 100 + i;\n            collection.Add(value);\n            Console.WriteLine($\"[Producer {producerId}] Added: {value}\");\n            Thread.Sleep(Random.Shared.Next(50, 150));\n        }\n        Console.WriteLine($\"[Producer {producerId}] Finished\");\n    })\n).ToArray();\n\n// Чекаємо поки всі producers завершать роботу\nTask.Run(async () =>\n{\n    await Task.WhenAll(producers);\n    collection.CompleteAdding();\n    Console.WriteLine(\"[Coordinator] All producers finished, CompleteAdding called\");\n});\n\n// 2 Consumers: обробляють числа\nvar consumers = Enumerable.Range(0, 2).Select(consumerId =>\n    Task.Run(() =>\n    {\n        foreach (int value in collection.GetConsumingEnumerable())\n        {\n            Console.WriteLine($\"[Consumer {consumerId}] Processing: {value}\");\n            Thread.Sleep(Random.Shared.Next(100, 200));\n        }\n        Console.WriteLine($\"[Consumer {consumerId}] No more items\");\n    })\n).ToArray();\n\nawait Task.WhenAll(consumers);\nConsole.WriteLine(\"Pipeline completed!\");\n","MultiProducerConsumer.cs",[2968,12755,12756,12764,12780,12792,12808,12812,12838,12842,12847,12884,12895,12899,12927,12931,12952,12967,12999,13029,13033,13056,13061,13069,13073,13078,13094,13098,13116,13126,13141,13145,13149,13154,13188,13198,13202,13222,13226,13257,13287,13291,13314,13318,13326,13330,13347],{"__ignoreMap":3051},[3055,12757,12758,12760,12762],{"class":3057,"line":3058},[3055,12759,3062],{"class":3061},[3055,12761,3066],{"class":3065},[3055,12763,3070],{"class":3069},[3055,12765,12766,12768,12770,12772,12774,12776,12778],{"class":3057,"line":3073},[3055,12767,3062],{"class":3061},[3055,12769,3066],{"class":3065},[3055,12771,3080],{"class":3069},[3055,12773,3083],{"class":3065},[3055,12775,3080],{"class":3069},[3055,12777,6738],{"class":3065},[3055,12779,3070],{"class":3069},[3055,12781,12782,12784,12786,12788,12790],{"class":3057,"line":3093},[3055,12783,3062],{"class":3061},[3055,12785,3066],{"class":3065},[3055,12787,3080],{"class":3069},[3055,12789,3102],{"class":3065},[3055,12791,3070],{"class":3069},[3055,12793,12794,12796,12798,12800,12802,12804,12806],{"class":3057,"line":3112},[3055,12795,3062],{"class":3061},[3055,12797,3066],{"class":3065},[3055,12799,3080],{"class":3069},[3055,12801,3102],{"class":3065},[3055,12803,3080],{"class":3069},[3055,12805,3107],{"class":3065},[3055,12807,3070],{"class":3069},[3055,12809,12810],{"class":3057,"line":3119},[3055,12811,3116],{"emptyLinePlaceholder":3115},[3055,12813,12814,12816,12818,12820,12822,12824,12826,12828,12830,12832,12834,12836],{"class":3057,"line":3148},[3055,12815,3123],{"class":3122},[3055,12817,11947],{"class":3126},[3055,12819,3130],{"class":3069},[3055,12821,3133],{"class":3122},[3055,12823,11954],{"class":3065},[3055,12825,3139],{"class":3069},[3055,12827,3142],{"class":3122},[3055,12829,7609],{"class":3069},[3055,12831,11963],{"class":3126},[3055,12833,5292],{"class":3069},[3055,12835,10321],{"class":3175},[3055,12837,3324],{"class":3069},[3055,12839,12840],{"class":3057,"line":3153},[3055,12841,3116],{"emptyLinePlaceholder":3115},[3055,12843,12844],{"class":3057,"line":3160},[3055,12845,12846],{"class":3156},"// 3 Producers: генерують числа\n",[3055,12848,12849,12851,12854,12856,12859,12861,12864,12866,12868,12870,12872,12875,12877,12879,12882],{"class":3057,"line":3192},[3055,12850,3123],{"class":3122},[3055,12852,12853],{"class":3126}," producers",[3055,12855,3130],{"class":3069},[3055,12857,12858],{"class":3126},"Enumerable",[3055,12860,3080],{"class":3069},[3055,12862,12863],{"class":3168},"Range",[3055,12865,3172],{"class":3069},[3055,12867,3176],{"class":3175},[3055,12869,2971],{"class":3069},[3055,12871,9223],{"class":3175},[3055,12873,12874],{"class":3069},").",[3055,12876,8156],{"class":3168},[3055,12878,3172],{"class":3069},[3055,12880,12881],{"class":3126},"producerId",[3055,12883,3189],{"class":3069},[3055,12885,12886,12889,12891,12893],{"class":3057,"line":3198},[3055,12887,12888],{"class":3126},"    Task",[3055,12890,3080],{"class":3069},[3055,12892,9583],{"class":3168},[3055,12894,9586],{"class":3069},[3055,12896,12897],{"class":3057,"line":3235},[3055,12898,3238],{"class":3069},[3055,12900,12901,12903,12905,12907,12909,12911,12913,12915,12917,12919,12921,12923,12925],{"class":3057,"line":3241},[3055,12902,3636],{"class":3061},[3055,12904,3204],{"class":3069},[3055,12906,3142],{"class":3122},[3055,12908,5444],{"class":3126},[3055,12910,3130],{"class":3069},[3055,12912,3176],{"class":3175},[3055,12914,3216],{"class":3069},[3055,12916,3186],{"class":3126},[3055,12918,3222],{"class":3069},[3055,12920,3181],{"class":3175},[3055,12922,3216],{"class":3069},[3055,12924,3186],{"class":3126},[3055,12926,3232],{"class":3069},[3055,12928,12929],{"class":3057,"line":3272},[3055,12930,3665],{"class":3069},[3055,12932,12933,12936,12938,12940,12942,12944,12946,12948,12950],{"class":3057,"line":3278},[3055,12934,12935],{"class":3122},"            int",[3055,12937,4912],{"class":3126},[3055,12939,3130],{"class":3069},[3055,12941,12881],{"class":3126},[3055,12943,3256],{"class":3069},[3055,12945,4693],{"class":3175},[3055,12947,3261],{"class":3069},[3055,12949,3186],{"class":3126},[3055,12951,3070],{"class":3069},[3055,12953,12954,12957,12959,12961,12963,12965],{"class":3057,"line":3284},[3055,12955,12956],{"class":3126},"            collection",[3055,12958,3080],{"class":3069},[3055,12960,3249],{"class":3168},[3055,12962,3172],{"class":3069},[3055,12964,4937],{"class":3126},[3055,12966,3324],{"class":3069},[3055,12968,12969,12971,12973,12975,12977,12980,12982,12984,12986,12989,12991,12993,12995,12997],{"class":3057,"line":3289},[3055,12970,8418],{"class":3126},[3055,12972,3080],{"class":3069},[3055,12974,3297],{"class":3168},[3055,12976,3172],{"class":3069},[3055,12978,12979],{"class":3302},"$\"[Producer ",[3055,12981,3307],{"class":3306},[3055,12983,12881],{"class":3126},[3055,12985,3318],{"class":3306},[3055,12987,12988],{"class":3302},"] Added: ",[3055,12990,3307],{"class":3306},[3055,12992,4937],{"class":3126},[3055,12994,3318],{"class":3306},[3055,12996,3321],{"class":3302},[3055,12998,3324],{"class":3069},[3055,13000,13001,13003,13005,13007,13009,13011,13013,13015,13017,13019,13021,13023,13025,13027],{"class":3057,"line":3327},[3055,13002,9844],{"class":3126},[3055,13004,3080],{"class":3069},[3055,13006,7770],{"class":3168},[3055,13008,3172],{"class":3069},[3055,13010,9706],{"class":3126},[3055,13012,3080],{"class":3069},[3055,13014,9711],{"class":3126},[3055,13016,3080],{"class":3069},[3055,13018,9716],{"class":3168},[3055,13020,3172],{"class":3069},[3055,13022,5295],{"class":3175},[3055,13024,2971],{"class":3069},[3055,13026,9725],{"class":3175},[3055,13028,7623],{"class":3069},[3055,13030,13031],{"class":3057,"line":3333},[3055,13032,3728],{"class":3069},[3055,13034,13035,13037,13039,13041,13043,13045,13047,13049,13051,13054],{"class":3057,"line":3338},[3055,13036,5416],{"class":3126},[3055,13038,3080],{"class":3069},[3055,13040,3297],{"class":3168},[3055,13042,3172],{"class":3069},[3055,13044,12979],{"class":3302},[3055,13046,3307],{"class":3306},[3055,13048,12881],{"class":3126},[3055,13050,3318],{"class":3306},[3055,13052,13053],{"class":3302},"] Finished\"",[3055,13055,3324],{"class":3069},[3055,13057,13058],{"class":3057,"line":3755},[3055,13059,13060],{"class":3069},"    })\n",[3055,13062,13063,13065,13067],{"class":3057,"line":3760},[3055,13064,12874],{"class":3069},[3055,13066,11525],{"class":3168},[3055,13068,4071],{"class":3069},[3055,13070,13071],{"class":3057,"line":3797},[3055,13072,3116],{"emptyLinePlaceholder":3115},[3055,13074,13075],{"class":3057,"line":3826},[3055,13076,13077],{"class":3156},"// Чекаємо поки всі producers завершать роботу\n",[3055,13079,13080,13082,13084,13086,13088,13091],{"class":3057,"line":3831},[3055,13081,9578],{"class":3126},[3055,13083,3080],{"class":3069},[3055,13085,9583],{"class":3168},[3055,13087,3172],{"class":3069},[3055,13089,13090],{"class":3122},"async",[3055,13092,13093],{"class":3069}," () =>\n",[3055,13095,13096],{"class":3057,"line":3836},[3055,13097,3195],{"class":3069},[3055,13099,13100,13103,13105,13107,13109,13111,13114],{"class":3057,"line":3842},[3055,13101,13102],{"class":3122},"    await",[3055,13104,9933],{"class":3126},[3055,13106,3080],{"class":3069},[3055,13108,9971],{"class":3168},[3055,13110,3172],{"class":3069},[3055,13112,13113],{"class":3126},"producers",[3055,13115,3324],{"class":3069},[3055,13117,13118,13120,13122,13124],{"class":3057,"line":3848},[3055,13119,12549],{"class":3126},[3055,13121,3080],{"class":3069},[3055,13123,11899],{"class":3168},[3055,13125,4071],{"class":3069},[3055,13127,13128,13130,13132,13134,13136,13139],{"class":3057,"line":3854},[3055,13129,3763],{"class":3126},[3055,13131,3080],{"class":3069},[3055,13133,3297],{"class":3168},[3055,13135,3172],{"class":3069},[3055,13137,13138],{"class":3302},"\"[Coordinator] All producers finished, CompleteAdding called\"",[3055,13140,3324],{"class":3069},[3055,13142,13143],{"class":3057,"line":4603},[3055,13144,3281],{"class":3069},[3055,13146,13147],{"class":3057,"line":4609},[3055,13148,3116],{"emptyLinePlaceholder":3115},[3055,13150,13151],{"class":3057,"line":7082},[3055,13152,13153],{"class":3156},"// 2 Consumers: обробляють числа\n",[3055,13155,13156,13158,13161,13163,13165,13167,13169,13171,13173,13175,13177,13179,13181,13183,13186],{"class":3057,"line":7095},[3055,13157,3123],{"class":3122},[3055,13159,13160],{"class":3126}," consumers",[3055,13162,3130],{"class":3069},[3055,13164,12858],{"class":3126},[3055,13166,3080],{"class":3069},[3055,13168,12863],{"class":3168},[3055,13170,3172],{"class":3069},[3055,13172,3176],{"class":3175},[3055,13174,2971],{"class":3069},[3055,13176,5278],{"class":3175},[3055,13178,12874],{"class":3069},[3055,13180,8156],{"class":3168},[3055,13182,3172],{"class":3069},[3055,13184,13185],{"class":3126},"consumerId",[3055,13187,3189],{"class":3069},[3055,13189,13190,13192,13194,13196],{"class":3057,"line":7104},[3055,13191,12888],{"class":3126},[3055,13193,3080],{"class":3069},[3055,13195,9583],{"class":3168},[3055,13197,9586],{"class":3069},[3055,13199,13200],{"class":3057,"line":7109},[3055,13201,3238],{"class":3069},[3055,13203,13204,13206,13208,13210,13212,13214,13216,13218,13220],{"class":3057,"line":7114},[3055,13205,8187],{"class":3061},[3055,13207,3204],{"class":3069},[3055,13209,3142],{"class":3122},[3055,13211,4912],{"class":3126},[3055,13213,5967],{"class":3061},[3055,13215,11947],{"class":3126},[3055,13217,3080],{"class":3069},[3055,13219,12634],{"class":3168},[3055,13221,12637],{"class":3069},[3055,13223,13224],{"class":3057,"line":7152},[3055,13225,3665],{"class":3069},[3055,13227,13228,13230,13232,13234,13236,13239,13241,13243,13245,13247,13249,13251,13253,13255],{"class":3057,"line":7157},[3055,13229,8418],{"class":3126},[3055,13231,3080],{"class":3069},[3055,13233,3297],{"class":3168},[3055,13235,3172],{"class":3069},[3055,13237,13238],{"class":3302},"$\"[Consumer ",[3055,13240,3307],{"class":3306},[3055,13242,13185],{"class":3126},[3055,13244,3318],{"class":3306},[3055,13246,11377],{"class":3302},[3055,13248,3307],{"class":3306},[3055,13250,4937],{"class":3126},[3055,13252,3318],{"class":3306},[3055,13254,3321],{"class":3302},[3055,13256,3324],{"class":3069},[3055,13258,13259,13261,13263,13265,13267,13269,13271,13273,13275,13277,13279,13281,13283,13285],{"class":3057,"line":7187},[3055,13260,9844],{"class":3126},[3055,13262,3080],{"class":3069},[3055,13264,7770],{"class":3168},[3055,13266,3172],{"class":3069},[3055,13268,9706],{"class":3126},[3055,13270,3080],{"class":3069},[3055,13272,9711],{"class":3126},[3055,13274,3080],{"class":3069},[3055,13276,9716],{"class":3168},[3055,13278,3172],{"class":3069},[3055,13280,4693],{"class":3175},[3055,13282,2971],{"class":3069},[3055,13284,4752],{"class":3175},[3055,13286,7623],{"class":3069},[3055,13288,13289],{"class":3057,"line":7211},[3055,13290,3728],{"class":3069},[3055,13292,13293,13295,13297,13299,13301,13303,13305,13307,13309,13312],{"class":3057,"line":7216},[3055,13294,5416],{"class":3126},[3055,13296,3080],{"class":3069},[3055,13298,3297],{"class":3168},[3055,13300,3172],{"class":3069},[3055,13302,13238],{"class":3302},[3055,13304,3307],{"class":3306},[3055,13306,13185],{"class":3126},[3055,13308,3318],{"class":3306},[3055,13310,13311],{"class":3302},"] No more items\"",[3055,13313,3324],{"class":3069},[3055,13315,13316],{"class":3057,"line":7235},[3055,13317,13060],{"class":3069},[3055,13319,13320,13322,13324],{"class":3057,"line":7240},[3055,13321,12874],{"class":3069},[3055,13323,11525],{"class":3168},[3055,13325,4071],{"class":3069},[3055,13327,13328],{"class":3057,"line":7245},[3055,13329,3116],{"emptyLinePlaceholder":3115},[3055,13331,13332,13334,13336,13338,13340,13342,13345],{"class":3057,"line":7293},[3055,13333,9930],{"class":3122},[3055,13335,9933],{"class":3126},[3055,13337,3080],{"class":3069},[3055,13339,9971],{"class":3168},[3055,13341,3172],{"class":3069},[3055,13343,13344],{"class":3126},"consumers",[3055,13346,3324],{"class":3069},[3055,13348,13349,13351,13353,13355,13357,13360],{"class":3057,"line":7298},[3055,13350,3292],{"class":3126},[3055,13352,3080],{"class":3069},[3055,13354,3297],{"class":3168},[3055,13356,3172],{"class":3069},[3055,13358,13359],{"class":3302},"\"Pipeline completed!\"",[3055,13361,3324],{"class":3069},[2964,13363,13364,3490],{},[2977,13365,8873],{},[3044,13367,13370],{"className":13368,"code":13369,"language":3496},[3494],"[Producer 0] Added: 0\n[Producer 1] Added: 100\n[Consumer 0] Processing: 0\n[Producer 2] Added: 200\n[Consumer 1] Processing: 100\n[Producer 0] Added: 1\n...\n[Producer 2] Finished\n[Coordinator] All producers finished, CompleteAdding called\n[Consumer 0] Processing: 209\n[Consumer 1] No more items\n[Consumer 0] No more items\nPipeline completed!\n",[2968,13371,13369],{"__ignoreMap":3051},[3032,13373,13375],{"id":13374},"коли-використовувати-blockingcollection","Коли Використовувати BlockingCollection",[2964,13377,13378,3490],{},[2977,13379,13380],{},"✅ Використовуйте BlockingCollection коли",[3009,13382,13383,13390,13397,13404],{},[3012,13384,13385,13386,13389],{},"Потрібен ",[2977,13387,13388],{},"bounded"," producer-consumer pattern (обмеження розміру черги)",[3012,13391,13392,13393,13396],{},"Producer швидший за Consumer і потрібно ",[2977,13394,13395],{},"backpressure"," (producer чекає поки consumer обробить)",[3012,13398,13399,13400,13403],{},"Потрібна ",[2977,13401,13402],{},"блокуюча"," семантика (потоки чекають замість busy-waiting)",[3012,13405,13406,13407,13410],{},"Працюєте з ",[2977,13408,13409],{},"синхронним"," кодом (не async/await)",[2964,13412,13413,3490],{},[2977,13414,13415],{},"❌ НЕ використовуйте BlockingCollection коли",[3009,13417,13418,13428,13434],{},[3012,13419,13406,13420,13423,13424,13427],{},[2977,13421,13422],{},"async/await"," → використовуйте ",[2968,13425,13426],{},"System.Threading.Channels"," (тема 15)",[3012,13429,13430,13431,13433],{},"Не потрібен bounded capacity → ",[2968,13432,9070],{}," простіший",[3012,13435,13436],{},"Потрібна висока throughput без блокування → lock-free колекції",[3025,13438],{},[2959,13440,13442],{"id":13441},"immutable-collections","Immutable Collections",[3032,13444,13446],{"id":13445},"концепція-thread-safety-через-immutability","Концепція: Thread Safety через Immutability",[2964,13448,13449,13452,13453,13456,13457,13460],{},[2977,13450,13451],{},"Immutable collections"," — колекції що ",[2977,13454,13455],{},"ніколи не змінюються"," після створення. Будь-яка \"модифікація\" створює ",[2977,13458,13459],{},"нову"," колекцію, залишаючи оригінал незмінним.",[2964,13462,13463],{},[2977,13464,13465],{},"Чому це thread-safe?",[2964,13467,13468,13469,13472],{},"Якщо ніхто не може змінити колекцію, то немає race conditions! Кілька потоків можуть ",[2977,13470,13471],{},"безпечно читати"," одну і ту саму immutable колекцію без будь-якої синхронізації.",[3044,13474,13476],{"className":3046,"code":13475,"language":3049,"meta":3051,"style":3051},"// Concurrent collections: thread-safe через locks/CAS\nvar concurrent = new ConcurrentDictionary\u003Cstring, int>();\nconcurrent[\"key\"] = 1;  // Модифікує існуючу колекцію\n\n// Immutable collections: thread-safe через immutability\nvar immutable = ImmutableDictionary\u003Cstring, int>.Empty;\nvar newImmutable = immutable.Add(\"key\", 1);  // Створює НОВУ колекцію\n// immutable досі порожній!\n// newImmutable містить один елемент\n",[2968,13477,13478,13483,13506,13525,13529,13534,13562,13591,13596],{"__ignoreMap":3051},[3055,13479,13480],{"class":3057,"line":3058},[3055,13481,13482],{"class":3156},"// Concurrent collections: thread-safe через locks/CAS\n",[3055,13484,13485,13487,13490,13492,13494,13496,13498,13500,13502,13504],{"class":3057,"line":3073},[3055,13486,3123],{"class":3122},[3055,13488,13489],{"class":3126}," concurrent",[3055,13491,3130],{"class":3069},[3055,13493,3133],{"class":3122},[3055,13495,4646],{"class":3065},[3055,13497,3139],{"class":3069},[3055,13499,3580],{"class":3122},[3055,13501,2971],{"class":3069},[3055,13503,3142],{"class":3122},[3055,13505,3145],{"class":3069},[3055,13507,13508,13511,13513,13516,13518,13520,13522],{"class":3057,"line":3093},[3055,13509,13510],{"class":3126},"concurrent",[3055,13512,3454],{"class":3069},[3055,13514,13515],{"class":3302},"\"key\"",[3055,13517,3459],{"class":3069},[3055,13519,3433],{"class":3175},[3055,13521,3465],{"class":3069},[3055,13523,13524],{"class":3156},"// Модифікує існуючу колекцію\n",[3055,13526,13527],{"class":3057,"line":3112},[3055,13528,3116],{"emptyLinePlaceholder":3115},[3055,13530,13531],{"class":3057,"line":3119},[3055,13532,13533],{"class":3156},"// Immutable collections: thread-safe через immutability\n",[3055,13535,13536,13538,13541,13543,13546,13548,13550,13552,13554,13557,13560],{"class":3057,"line":3148},[3055,13537,3123],{"class":3122},[3055,13539,13540],{"class":3126}," immutable",[3055,13542,3130],{"class":3069},[3055,13544,13545],{"class":3126},"ImmutableDictionary",[3055,13547,3139],{"class":3069},[3055,13549,3580],{"class":3122},[3055,13551,2971],{"class":3069},[3055,13553,3142],{"class":3122},[3055,13555,13556],{"class":3069},">.",[3055,13558,13559],{"class":3126},"Empty",[3055,13561,3070],{"class":3069},[3055,13563,13564,13566,13569,13571,13574,13576,13578,13580,13582,13584,13586,13588],{"class":3057,"line":3153},[3055,13565,3123],{"class":3122},[3055,13567,13568],{"class":3126}," newImmutable",[3055,13570,3130],{"class":3069},[3055,13572,13573],{"class":3126},"immutable",[3055,13575,3080],{"class":3069},[3055,13577,3249],{"class":3168},[3055,13579,3172],{"class":3069},[3055,13581,13515],{"class":3302},[3055,13583,2971],{"class":3069},[3055,13585,3433],{"class":3175},[3055,13587,3266],{"class":3069},[3055,13589,13590],{"class":3156},"// Створює НОВУ колекцію\n",[3055,13592,13593],{"class":3057,"line":3160},[3055,13594,13595],{"class":3156},"// immutable досі порожній!\n",[3055,13597,13598],{"class":3057,"line":3192},[3055,13599,13600],{"class":3156},"// newImmutable містить один елемент\n",[2964,13602,13603,13606,13607,13610],{},[2977,13604,13605],{},"Аналогія",": Immutable колекція — це як ",[2977,13608,13609],{},"фотографія",". Ви не можете змінити фотографію, але можете зробити нову з додатковими елементами.",[3032,13612,13614],{"id":13613},"встановлення","Встановлення",[2964,13616,13617,13618,3490],{},"Immutable collections знаходяться у NuGet пакеті ",[2968,13619,13620],{},"System.Collections.Immutable",[3044,13622,13626],{"className":13623,"code":13624,"language":13625,"meta":3051,"style":3051},"language-bash shiki shiki-themes light-plus dark-plus dark-plus","dotnet add package System.Collections.Immutable\n","bash",[2968,13627,13628],{"__ignoreMap":3051},[3055,13629,13630,13633,13636,13639],{"class":3057,"line":3058},[3055,13631,13632],{"class":3168},"dotnet",[3055,13634,13635],{"class":3302}," add",[3055,13637,13638],{"class":3302}," package",[3055,13640,13641],{"class":3302}," System.Collections.Immutable\n",[3032,13643,13645,13646],{"id":13644},"immutablelist","ImmutableList",[3037,13647],{},[3044,13649,13652],{"className":3046,"code":13650,"filename":13651,"language":3049,"meta":3050,"style":3051},"using System.Collections.Immutable;\n\n// Створення порожнього списку\nvar list1 = ImmutableList\u003Cint>.Empty;\nConsole.WriteLine($\"list1.Count: {list1.Count}\");  // 0\n\n// Add створює НОВУ колекцію\nvar list2 = list1.Add(10);\nConsole.WriteLine($\"list1.Count: {list1.Count}\");  // 0 (не змінився!)\nConsole.WriteLine($\"list2.Count: {list2.Count}\");  // 1\n\n// Можна ланцюжком\nvar list3 = list2.Add(20).Add(30).Add(40);\nConsole.WriteLine($\"list3: [{string.Join(\", \", list3)}]\");  // [10, 20, 30, 40]\n\n// Remove також створює нову колекцію\nvar list4 = list3.Remove(20);\nConsole.WriteLine($\"list3: [{string.Join(\", \", list3)}]\");  // [10, 20, 30, 40] (не змінився)\nConsole.WriteLine($\"list4: [{string.Join(\", \", list4)}]\");  // [10, 30, 40]\n\n// Індексація (read-only)\nConsole.WriteLine($\"list3[1]: {list3[1]}\");  // 20\n\n// SetItem — \"змінити\" елемент за індексом (створює нову колекцію)\nvar list5 = list3.SetItem(1, 999);\nConsole.WriteLine($\"list3: [{string.Join(\", \", list3)}]\");  // [10, 20, 30, 40]\nConsole.WriteLine($\"list5: [{string.Join(\", \", list5)}]\");  // [10, 999, 30, 40]\n","ImmutableListBasics.cs",[2968,13653,13654,13671,13675,13680,13701,13732,13736,13741,13762,13791,13821,13825,13830,13868,13908,13912,13917,13939,13976,14015,14019,14024,14054,14058,14063,14090,14126],{"__ignoreMap":3051},[3055,13655,13656,13658,13660,13662,13664,13666,13669],{"class":3057,"line":3058},[3055,13657,3062],{"class":3061},[3055,13659,3066],{"class":3065},[3055,13661,3080],{"class":3069},[3055,13663,3083],{"class":3065},[3055,13665,3080],{"class":3069},[3055,13667,13668],{"class":3065},"Immutable",[3055,13670,3070],{"class":3069},[3055,13672,13673],{"class":3057,"line":3073},[3055,13674,3116],{"emptyLinePlaceholder":3115},[3055,13676,13677],{"class":3057,"line":3093},[3055,13678,13679],{"class":3156},"// Створення порожнього списку\n",[3055,13681,13682,13684,13687,13689,13691,13693,13695,13697,13699],{"class":3057,"line":3112},[3055,13683,3123],{"class":3122},[3055,13685,13686],{"class":3126}," list1",[3055,13688,3130],{"class":3069},[3055,13690,13645],{"class":3126},[3055,13692,3139],{"class":3069},[3055,13694,3142],{"class":3122},[3055,13696,13556],{"class":3069},[3055,13698,13559],{"class":3126},[3055,13700,3070],{"class":3069},[3055,13702,13703,13705,13707,13709,13711,13714,13716,13719,13721,13723,13725,13727,13729],{"class":3057,"line":3119},[3055,13704,3292],{"class":3126},[3055,13706,3080],{"class":3069},[3055,13708,3297],{"class":3168},[3055,13710,3172],{"class":3069},[3055,13712,13713],{"class":3302},"$\"list1.Count: ",[3055,13715,3307],{"class":3306},[3055,13717,13718],{"class":3126},"list1",[3055,13720,3080],{"class":3306},[3055,13722,3315],{"class":3126},[3055,13724,3318],{"class":3306},[3055,13726,3321],{"class":3302},[3055,13728,3266],{"class":3069},[3055,13730,13731],{"class":3156},"// 0\n",[3055,13733,13734],{"class":3057,"line":3148},[3055,13735,3116],{"emptyLinePlaceholder":3115},[3055,13737,13738],{"class":3057,"line":3153},[3055,13739,13740],{"class":3156},"// Add створює НОВУ колекцію\n",[3055,13742,13743,13745,13748,13750,13752,13754,13756,13758,13760],{"class":3057,"line":3160},[3055,13744,3123],{"class":3122},[3055,13746,13747],{"class":3126}," list2",[3055,13749,3130],{"class":3069},[3055,13751,13718],{"class":3126},[3055,13753,3080],{"class":3069},[3055,13755,3249],{"class":3168},[3055,13757,3172],{"class":3069},[3055,13759,3181],{"class":3175},[3055,13761,3324],{"class":3069},[3055,13763,13764,13766,13768,13770,13772,13774,13776,13778,13780,13782,13784,13786,13788],{"class":3057,"line":3192},[3055,13765,3292],{"class":3126},[3055,13767,3080],{"class":3069},[3055,13769,3297],{"class":3168},[3055,13771,3172],{"class":3069},[3055,13773,13713],{"class":3302},[3055,13775,3307],{"class":3306},[3055,13777,13718],{"class":3126},[3055,13779,3080],{"class":3306},[3055,13781,3315],{"class":3126},[3055,13783,3318],{"class":3306},[3055,13785,3321],{"class":3302},[3055,13787,3266],{"class":3069},[3055,13789,13790],{"class":3156},"// 0 (не змінився!)\n",[3055,13792,13793,13795,13797,13799,13801,13804,13806,13809,13811,13813,13815,13817,13819],{"class":3057,"line":3198},[3055,13794,3292],{"class":3126},[3055,13796,3080],{"class":3069},[3055,13798,3297],{"class":3168},[3055,13800,3172],{"class":3069},[3055,13802,13803],{"class":3302},"$\"list2.Count: ",[3055,13805,3307],{"class":3306},[3055,13807,13808],{"class":3126},"list2",[3055,13810,3080],{"class":3306},[3055,13812,3315],{"class":3126},[3055,13814,3318],{"class":3306},[3055,13816,3321],{"class":3302},[3055,13818,3266],{"class":3069},[3055,13820,12121],{"class":3156},[3055,13822,13823],{"class":3057,"line":3235},[3055,13824,3116],{"emptyLinePlaceholder":3115},[3055,13826,13827],{"class":3057,"line":3241},[3055,13828,13829],{"class":3156},"// Можна ланцюжком\n",[3055,13831,13832,13834,13837,13839,13841,13843,13845,13847,13849,13851,13853,13855,13857,13859,13861,13863,13866],{"class":3057,"line":3272},[3055,13833,3123],{"class":3122},[3055,13835,13836],{"class":3126}," list3",[3055,13838,3130],{"class":3069},[3055,13840,13808],{"class":3126},[3055,13842,3080],{"class":3069},[3055,13844,3249],{"class":3168},[3055,13846,3172],{"class":3069},[3055,13848,10321],{"class":3175},[3055,13850,12874],{"class":3069},[3055,13852,3249],{"class":3168},[3055,13854,3172],{"class":3069},[3055,13856,10326],{"class":3175},[3055,13858,12874],{"class":3069},[3055,13860,3249],{"class":3168},[3055,13862,3172],{"class":3069},[3055,13864,13865],{"class":3175},"40",[3055,13867,3324],{"class":3069},[3055,13869,13870,13872,13874,13876,13878,13881,13883,13885,13887,13889,13891,13893,13895,13898,13900,13903,13905],{"class":3057,"line":3278},[3055,13871,3292],{"class":3126},[3055,13873,3080],{"class":3069},[3055,13875,3297],{"class":3168},[3055,13877,3172],{"class":3069},[3055,13879,13880],{"class":3302},"$\"list3: [",[3055,13882,3307],{"class":3306},[3055,13884,3580],{"class":3122},[3055,13886,3080],{"class":3306},[3055,13888,10429],{"class":3168},[3055,13890,3172],{"class":3306},[3055,13892,10434],{"class":3302},[3055,13894,2971],{"class":3306},[3055,13896,13897],{"class":3126},"list3",[3055,13899,8726],{"class":3306},[3055,13901,13902],{"class":3302},"]\"",[3055,13904,3266],{"class":3069},[3055,13906,13907],{"class":3156},"// [10, 20, 30, 40]\n",[3055,13909,13910],{"class":3057,"line":3284},[3055,13911,3116],{"emptyLinePlaceholder":3115},[3055,13913,13914],{"class":3057,"line":3289},[3055,13915,13916],{"class":3156},"// Remove також створює нову колекцію\n",[3055,13918,13919,13921,13924,13926,13928,13930,13933,13935,13937],{"class":3057,"line":3327},[3055,13920,3123],{"class":3122},[3055,13922,13923],{"class":3126}," list4",[3055,13925,3130],{"class":3069},[3055,13927,13897],{"class":3126},[3055,13929,3080],{"class":3069},[3055,13931,13932],{"class":3168},"Remove",[3055,13934,3172],{"class":3069},[3055,13936,10321],{"class":3175},[3055,13938,3324],{"class":3069},[3055,13940,13941,13943,13945,13947,13949,13951,13953,13955,13957,13959,13961,13963,13965,13967,13969,13971,13973],{"class":3057,"line":3333},[3055,13942,3292],{"class":3126},[3055,13944,3080],{"class":3069},[3055,13946,3297],{"class":3168},[3055,13948,3172],{"class":3069},[3055,13950,13880],{"class":3302},[3055,13952,3307],{"class":3306},[3055,13954,3580],{"class":3122},[3055,13956,3080],{"class":3306},[3055,13958,10429],{"class":3168},[3055,13960,3172],{"class":3306},[3055,13962,10434],{"class":3302},[3055,13964,2971],{"class":3306},[3055,13966,13897],{"class":3126},[3055,13968,8726],{"class":3306},[3055,13970,13902],{"class":3302},[3055,13972,3266],{"class":3069},[3055,13974,13975],{"class":3156},"// [10, 20, 30, 40] (не змінився)\n",[3055,13977,13978,13980,13982,13984,13986,13989,13991,13993,13995,13997,13999,14001,14003,14006,14008,14010,14012],{"class":3057,"line":3338},[3055,13979,3292],{"class":3126},[3055,13981,3080],{"class":3069},[3055,13983,3297],{"class":3168},[3055,13985,3172],{"class":3069},[3055,13987,13988],{"class":3302},"$\"list4: [",[3055,13990,3307],{"class":3306},[3055,13992,3580],{"class":3122},[3055,13994,3080],{"class":3306},[3055,13996,10429],{"class":3168},[3055,13998,3172],{"class":3306},[3055,14000,10434],{"class":3302},[3055,14002,2971],{"class":3306},[3055,14004,14005],{"class":3126},"list4",[3055,14007,8726],{"class":3306},[3055,14009,13902],{"class":3302},[3055,14011,3266],{"class":3069},[3055,14013,14014],{"class":3156},"// [10, 30, 40]\n",[3055,14016,14017],{"class":3057,"line":3755},[3055,14018,3116],{"emptyLinePlaceholder":3115},[3055,14020,14021],{"class":3057,"line":3760},[3055,14022,14023],{"class":3156},"// Індексація (read-only)\n",[3055,14025,14026,14028,14030,14032,14034,14037,14039,14041,14043,14045,14047,14049,14051],{"class":3057,"line":3797},[3055,14027,3292],{"class":3126},[3055,14029,3080],{"class":3069},[3055,14031,3297],{"class":3168},[3055,14033,3172],{"class":3069},[3055,14035,14036],{"class":3302},"$\"list3[1]: ",[3055,14038,3307],{"class":3306},[3055,14040,13897],{"class":3126},[3055,14042,3454],{"class":3306},[3055,14044,3433],{"class":3175},[3055,14046,4807],{"class":3306},[3055,14048,3321],{"class":3302},[3055,14050,3266],{"class":3069},[3055,14052,14053],{"class":3156},"// 20\n",[3055,14055,14056],{"class":3057,"line":3826},[3055,14057,3116],{"emptyLinePlaceholder":3115},[3055,14059,14060],{"class":3057,"line":3831},[3055,14061,14062],{"class":3156},"// SetItem — \"змінити\" елемент за індексом (створює нову колекцію)\n",[3055,14064,14065,14067,14070,14072,14074,14076,14079,14081,14083,14085,14088],{"class":3057,"line":3836},[3055,14066,3123],{"class":3122},[3055,14068,14069],{"class":3126}," list5",[3055,14071,3130],{"class":3069},[3055,14073,13897],{"class":3126},[3055,14075,3080],{"class":3069},[3055,14077,14078],{"class":3168},"SetItem",[3055,14080,3172],{"class":3069},[3055,14082,3433],{"class":3175},[3055,14084,2971],{"class":3069},[3055,14086,14087],{"class":3175},"999",[3055,14089,3324],{"class":3069},[3055,14091,14092,14094,14096,14098,14100,14102,14104,14106,14108,14110,14112,14114,14116,14118,14120,14122,14124],{"class":3057,"line":3842},[3055,14093,3292],{"class":3126},[3055,14095,3080],{"class":3069},[3055,14097,3297],{"class":3168},[3055,14099,3172],{"class":3069},[3055,14101,13880],{"class":3302},[3055,14103,3307],{"class":3306},[3055,14105,3580],{"class":3122},[3055,14107,3080],{"class":3306},[3055,14109,10429],{"class":3168},[3055,14111,3172],{"class":3306},[3055,14113,10434],{"class":3302},[3055,14115,2971],{"class":3306},[3055,14117,13897],{"class":3126},[3055,14119,8726],{"class":3306},[3055,14121,13902],{"class":3302},[3055,14123,3266],{"class":3069},[3055,14125,13907],{"class":3156},[3055,14127,14128,14130,14132,14134,14136,14139,14141,14143,14145,14147,14149,14151,14153,14156,14158,14160,14162],{"class":3057,"line":3848},[3055,14129,3292],{"class":3126},[3055,14131,3080],{"class":3069},[3055,14133,3297],{"class":3168},[3055,14135,3172],{"class":3069},[3055,14137,14138],{"class":3302},"$\"list5: [",[3055,14140,3307],{"class":3306},[3055,14142,3580],{"class":3122},[3055,14144,3080],{"class":3306},[3055,14146,10429],{"class":3168},[3055,14148,3172],{"class":3306},[3055,14150,10434],{"class":3302},[3055,14152,2971],{"class":3306},[3055,14154,14155],{"class":3126},"list5",[3055,14157,8726],{"class":3306},[3055,14159,13902],{"class":3302},[3055,14161,3266],{"class":3069},[3055,14163,14164],{"class":3156},"// [10, 999, 30, 40]\n",[2964,14166,14167,14169,14170,14173,14174,14177],{},[2977,14168,5320],{},": Кожна операція створює нову колекцію. Це може здаватись неефективним, але під капотом використовується ",[2977,14171,14172],{},"structural sharing"," — нові та старі версії ",[2977,14175,14176],{},"спільно використовують"," більшість даних.",[3032,14179,14181],{"id":14180},"structural-sharing-як-це-працює","Structural Sharing: Як Це Працює",[2964,14183,14184,14185,14188,14189,14192,14193,14196],{},"Immutable колекції використовують ",[2977,14186,14187],{},"persistent data structures"," (зокрема ",[2977,14190,14191],{},"AVL trees"," для списків та ",[2977,14194,14195],{},"Hash Array Mapped Trie"," для словників).",[2964,14198,14199,14200,3080],{},"Давайте детально розберемо як працює structural sharing на прикладі ",[2968,14201,14202],{},"ImmutableList\u003CT>",[2964,14204,14205,3490],{},[2977,14206,14207],{},"Наївний підхід (НЕ так як працює насправді)",[3044,14209,14211],{"className":3046,"code":14210,"language":3049,"meta":3051,"style":3051},"// Якби ImmutableList просто копіював весь масив:\nvar list1 = ImmutableList.Create(1, 2, 3, 4, 5);  // [1, 2, 3, 4, 5]\nvar list2 = list1.Add(6);  // Копіювання всіх 5 елементів + додавання 6\n\n// Проблема: O(n) час та O(n) пам'ять для кожної операції!\n",[2968,14212,14213,14218,14259,14283,14287],{"__ignoreMap":3051},[3055,14214,14215],{"class":3057,"line":3058},[3055,14216,14217],{"class":3156},"// Якби ImmutableList просто копіював весь масив:\n",[3055,14219,14220,14222,14224,14226,14228,14230,14233,14235,14237,14239,14241,14243,14245,14247,14250,14252,14254,14256],{"class":3057,"line":3073},[3055,14221,3123],{"class":3122},[3055,14223,13686],{"class":3126},[3055,14225,3130],{"class":3069},[3055,14227,13645],{"class":3126},[3055,14229,3080],{"class":3069},[3055,14231,14232],{"class":3168},"Create",[3055,14234,3172],{"class":3069},[3055,14236,3433],{"class":3175},[3055,14238,2971],{"class":3069},[3055,14240,5278],{"class":3175},[3055,14242,2971],{"class":3069},[3055,14244,9223],{"class":3175},[3055,14246,2971],{"class":3069},[3055,14248,14249],{"class":3175},"4",[3055,14251,2971],{"class":3069},[3055,14253,11550],{"class":3175},[3055,14255,3266],{"class":3069},[3055,14257,14258],{"class":3156},"// [1, 2, 3, 4, 5]\n",[3055,14260,14261,14263,14265,14267,14269,14271,14273,14275,14278,14280],{"class":3057,"line":3093},[3055,14262,3123],{"class":3122},[3055,14264,13747],{"class":3126},[3055,14266,3130],{"class":3069},[3055,14268,13718],{"class":3126},[3055,14270,3080],{"class":3069},[3055,14272,3249],{"class":3168},[3055,14274,3172],{"class":3069},[3055,14276,14277],{"class":3175},"6",[3055,14279,3266],{"class":3069},[3055,14281,14282],{"class":3156},"// Копіювання всіх 5 елементів + додавання 6\n",[3055,14284,14285],{"class":3057,"line":3112},[3055,14286,3116],{"emptyLinePlaceholder":3115},[3055,14288,14289],{"class":3057,"line":3119},[3055,14290,14291],{"class":3156},"// Проблема: O(n) час та O(n) пам'ять для кожної операції!\n",[2964,14293,14294],{},[2977,14295,14296],{},"Реальний підхід: AVL Tree з Structural Sharing",[2964,14298,14299,14301,14302,14305],{},[2968,14300,14202],{}," внутрішньо представлений як ",[2977,14303,14304],{},"збалансоване бінарне дерево"," (AVL tree), де кожен вузол містить елемент та посилання на лівого/правого нащадка.",[3044,14307,14310],{"className":14308,"code":14309,"language":3496},[3494],"Оригінальний список: [10, 20, 30]\n         Root\n        /    \\\n      [10]   Node\n            /    \\\n          [20]  [30]\n\nПісля Add(40): [10, 20, 30, 40]\n         NewRoot  ← Новий корінь\n        /    \\\n      [10]   NewNode  ← Новий вузол\n            /    \\\n          [20]  NewNode2  ← Новий вузол\n               /    \\\n             [30]  [40]\n\nСпільні вузли: [10], [20], [30] — НЕ копіюються!\nСтворено тільки: NewRoot, NewNode, NewNode2\n",[2968,14311,14309],{"__ignoreMap":3051},[2964,14313,14314],{},[2977,14315,14316],{},"Чому це ефективно?",[3877,14318,14319,14325,14331],{},[3012,14320,14321,14324],{},[2977,14322,14323],{},"Не копіюємо всі елементи"," — тільки шлях від кореня до нового елемента (O(log n) вузлів)",[3012,14326,14327,14330],{},[2977,14328,14329],{},"Старі версії залишаються валідними"," — вони посилаються на ті самі вузли",[3012,14332,14333,14336],{},[2977,14334,14335],{},"Garbage Collector очищає непотрібні вузли"," — коли на них більше немає посилань",[2964,14338,14339,3490],{},[2977,14340,14341],{},"Детальний приклад з кількома версіями",[3044,14343,14345],{"className":3046,"code":14344,"language":3049,"meta":3051,"style":3051},"var v1 = ImmutableList\u003Cint>.Empty;        // Версія 1: []\nvar v2 = v1.Add(10);                      // Версія 2: [10]\nvar v3 = v2.Add(20);                      // Версія 3: [10, 20]\nvar v4 = v3.Add(30);                      // Версія 4: [10, 20, 30]\n\n// Всі 4 версії існують одночасно!\nConsole.WriteLine($\"v1: [{string.Join(\", \", v1)}]\");  // []\nConsole.WriteLine($\"v2: [{string.Join(\", \", v2)}]\");  // [10]\nConsole.WriteLine($\"v3: [{string.Join(\", \", v3)}]\");  // [10, 20]\nConsole.WriteLine($\"v4: [{string.Join(\", \", v4)}]\");  // [10, 20, 30]\n",[2968,14346,14347,14372,14398,14423,14448,14452,14457,14495,14533,14571],{"__ignoreMap":3051},[3055,14348,14349,14351,14354,14356,14358,14360,14362,14364,14366,14369],{"class":3057,"line":3058},[3055,14350,3123],{"class":3122},[3055,14352,14353],{"class":3126}," v1",[3055,14355,3130],{"class":3069},[3055,14357,13645],{"class":3126},[3055,14359,3139],{"class":3069},[3055,14361,3142],{"class":3122},[3055,14363,13556],{"class":3069},[3055,14365,13559],{"class":3126},[3055,14367,14368],{"class":3069},";        ",[3055,14370,14371],{"class":3156},"// Версія 1: []\n",[3055,14373,14374,14376,14379,14381,14384,14386,14388,14390,14392,14395],{"class":3057,"line":3073},[3055,14375,3123],{"class":3122},[3055,14377,14378],{"class":3126}," v2",[3055,14380,3130],{"class":3069},[3055,14382,14383],{"class":3126},"v1",[3055,14385,3080],{"class":3069},[3055,14387,3249],{"class":3168},[3055,14389,3172],{"class":3069},[3055,14391,3181],{"class":3175},[3055,14393,14394],{"class":3069},");                      ",[3055,14396,14397],{"class":3156},"// Версія 2: [10]\n",[3055,14399,14400,14402,14405,14407,14410,14412,14414,14416,14418,14420],{"class":3057,"line":3093},[3055,14401,3123],{"class":3122},[3055,14403,14404],{"class":3126}," v3",[3055,14406,3130],{"class":3069},[3055,14408,14409],{"class":3126},"v2",[3055,14411,3080],{"class":3069},[3055,14413,3249],{"class":3168},[3055,14415,3172],{"class":3069},[3055,14417,10321],{"class":3175},[3055,14419,14394],{"class":3069},[3055,14421,14422],{"class":3156},"// Версія 3: [10, 20]\n",[3055,14424,14425,14427,14430,14432,14435,14437,14439,14441,14443,14445],{"class":3057,"line":3112},[3055,14426,3123],{"class":3122},[3055,14428,14429],{"class":3126}," v4",[3055,14431,3130],{"class":3069},[3055,14433,14434],{"class":3126},"v3",[3055,14436,3080],{"class":3069},[3055,14438,3249],{"class":3168},[3055,14440,3172],{"class":3069},[3055,14442,10326],{"class":3175},[3055,14444,14394],{"class":3069},[3055,14446,14447],{"class":3156},"// Версія 4: [10, 20, 30]\n",[3055,14449,14450],{"class":3057,"line":3119},[3055,14451,3116],{"emptyLinePlaceholder":3115},[3055,14453,14454],{"class":3057,"line":3148},[3055,14455,14456],{"class":3156},"// Всі 4 версії існують одночасно!\n",[3055,14458,14459,14461,14463,14465,14467,14470,14472,14474,14476,14478,14480,14482,14484,14486,14488,14490,14492],{"class":3057,"line":3153},[3055,14460,3292],{"class":3126},[3055,14462,3080],{"class":3069},[3055,14464,3297],{"class":3168},[3055,14466,3172],{"class":3069},[3055,14468,14469],{"class":3302},"$\"v1: [",[3055,14471,3307],{"class":3306},[3055,14473,3580],{"class":3122},[3055,14475,3080],{"class":3306},[3055,14477,10429],{"class":3168},[3055,14479,3172],{"class":3306},[3055,14481,10434],{"class":3302},[3055,14483,2971],{"class":3306},[3055,14485,14383],{"class":3126},[3055,14487,8726],{"class":3306},[3055,14489,13902],{"class":3302},[3055,14491,3266],{"class":3069},[3055,14493,14494],{"class":3156},"// []\n",[3055,14496,14497,14499,14501,14503,14505,14508,14510,14512,14514,14516,14518,14520,14522,14524,14526,14528,14530],{"class":3057,"line":3160},[3055,14498,3292],{"class":3126},[3055,14500,3080],{"class":3069},[3055,14502,3297],{"class":3168},[3055,14504,3172],{"class":3069},[3055,14506,14507],{"class":3302},"$\"v2: [",[3055,14509,3307],{"class":3306},[3055,14511,3580],{"class":3122},[3055,14513,3080],{"class":3306},[3055,14515,10429],{"class":3168},[3055,14517,3172],{"class":3306},[3055,14519,10434],{"class":3302},[3055,14521,2971],{"class":3306},[3055,14523,14409],{"class":3126},[3055,14525,8726],{"class":3306},[3055,14527,13902],{"class":3302},[3055,14529,3266],{"class":3069},[3055,14531,14532],{"class":3156},"// [10]\n",[3055,14534,14535,14537,14539,14541,14543,14546,14548,14550,14552,14554,14556,14558,14560,14562,14564,14566,14568],{"class":3057,"line":3192},[3055,14536,3292],{"class":3126},[3055,14538,3080],{"class":3069},[3055,14540,3297],{"class":3168},[3055,14542,3172],{"class":3069},[3055,14544,14545],{"class":3302},"$\"v3: [",[3055,14547,3307],{"class":3306},[3055,14549,3580],{"class":3122},[3055,14551,3080],{"class":3306},[3055,14553,10429],{"class":3168},[3055,14555,3172],{"class":3306},[3055,14557,10434],{"class":3302},[3055,14559,2971],{"class":3306},[3055,14561,14434],{"class":3126},[3055,14563,8726],{"class":3306},[3055,14565,13902],{"class":3302},[3055,14567,3266],{"class":3069},[3055,14569,14570],{"class":3156},"// [10, 20]\n",[3055,14572,14573,14575,14577,14579,14581,14584,14586,14588,14590,14592,14594,14596,14598,14601,14603,14605,14607],{"class":3057,"line":3198},[3055,14574,3292],{"class":3126},[3055,14576,3080],{"class":3069},[3055,14578,3297],{"class":3168},[3055,14580,3172],{"class":3069},[3055,14582,14583],{"class":3302},"$\"v4: [",[3055,14585,3307],{"class":3306},[3055,14587,3580],{"class":3122},[3055,14589,3080],{"class":3306},[3055,14591,10429],{"class":3168},[3055,14593,3172],{"class":3306},[3055,14595,10434],{"class":3302},[3055,14597,2971],{"class":3306},[3055,14599,14600],{"class":3126},"v4",[3055,14602,8726],{"class":3306},[3055,14604,13902],{"class":3302},[3055,14606,3266],{"class":3069},[3055,14608,14609],{"class":3156},"// [10, 20, 30]\n",[2964,14611,14612,3490],{},[2977,14613,14614],{},"Візуалізація пам'яті (спрощено)",[3044,14616,14619],{"className":14617,"code":14618,"language":3496},[3494],"v1 → null (порожній)\n\nv2 → Node(10)\n\nv3 → Node(20)\n       ↓\n     Node(10)  ← Спільний з v2!\n\nv4 → Node(30)\n       ↓\n     Node(20)  ← Спільний з v3!\n       ↓\n     Node(10)  ← Спільний з v2 та v3!\n",[2968,14620,14618],{"__ignoreMap":3051},[2964,14622,14623,14626],{},[2977,14624,14625],{},"Пам'ять",": Замість 6 елементів (0 + 1 + 2 + 3), зберігаємо тільки 3 унікальні вузли!",[2964,14628,14629,3490],{},[2977,14630,4465],{},[3917,14632,14633],{},[3044,14634,14636],{"className":3921,"code":14635,"language":3917,"meta":3051,"style":3051},"graph TD\n    subgraph \"Версія 1: []\"\n        V1[Empty]\n    end\n\n    subgraph \"Версія 2: [10]\"\n        V2[Root v2]\n        N10[Node: 10]\n        V2 --> N10\n    end\n\n    subgraph \"Версія 3: [10, 20]\"\n        V3[Root v3]\n        N20[Node: 20]\n        V3 --> N20\n        N20 -.Спільний.-> N10\n    end\n\n    subgraph \"Версія 4: [10, 20, 30]\"\n        V4[Root v4]\n        N30[Node: 30]\n        V4 --> N30\n        N30 -.Спільний.-> N20\n    end\n\n    style N10 fill:#3b82f6,stroke:#1d4ed8,color:#ffffff\n    style N20 fill:#3b82f6,stroke:#1d4ed8,color:#ffffff\n    style N30 fill:#3b82f6,stroke:#1d4ed8,color:#ffffff\n",[2968,14637,14638,14643,14648,14653,14658,14662,14667,14672,14677,14682,14686,14690,14695,14700,14705,14710,14715,14719,14723,14728,14733,14738,14743,14748,14752,14756,14761,14766],{"__ignoreMap":3051},[3055,14639,14640],{"class":3057,"line":3058},[3055,14641,14642],{},"graph TD\n",[3055,14644,14645],{"class":3057,"line":3073},[3055,14646,14647],{},"    subgraph \"Версія 1: []\"\n",[3055,14649,14650],{"class":3057,"line":3093},[3055,14651,14652],{},"        V1[Empty]\n",[3055,14654,14655],{"class":3057,"line":3112},[3055,14656,14657],{},"    end\n",[3055,14659,14660],{"class":3057,"line":3119},[3055,14661,3116],{"emptyLinePlaceholder":3115},[3055,14663,14664],{"class":3057,"line":3148},[3055,14665,14666],{},"    subgraph \"Версія 2: [10]\"\n",[3055,14668,14669],{"class":3057,"line":3153},[3055,14670,14671],{},"        V2[Root v2]\n",[3055,14673,14674],{"class":3057,"line":3160},[3055,14675,14676],{},"        N10[Node: 10]\n",[3055,14678,14679],{"class":3057,"line":3192},[3055,14680,14681],{},"        V2 --> N10\n",[3055,14683,14684],{"class":3057,"line":3198},[3055,14685,14657],{},[3055,14687,14688],{"class":3057,"line":3235},[3055,14689,3116],{"emptyLinePlaceholder":3115},[3055,14691,14692],{"class":3057,"line":3241},[3055,14693,14694],{},"    subgraph \"Версія 3: [10, 20]\"\n",[3055,14696,14697],{"class":3057,"line":3272},[3055,14698,14699],{},"        V3[Root v3]\n",[3055,14701,14702],{"class":3057,"line":3278},[3055,14703,14704],{},"        N20[Node: 20]\n",[3055,14706,14707],{"class":3057,"line":3284},[3055,14708,14709],{},"        V3 --> N20\n",[3055,14711,14712],{"class":3057,"line":3289},[3055,14713,14714],{},"        N20 -.Спільний.-> N10\n",[3055,14716,14717],{"class":3057,"line":3327},[3055,14718,14657],{},[3055,14720,14721],{"class":3057,"line":3333},[3055,14722,3116],{"emptyLinePlaceholder":3115},[3055,14724,14725],{"class":3057,"line":3338},[3055,14726,14727],{},"    subgraph \"Версія 4: [10, 20, 30]\"\n",[3055,14729,14730],{"class":3057,"line":3755},[3055,14731,14732],{},"        V4[Root v4]\n",[3055,14734,14735],{"class":3057,"line":3760},[3055,14736,14737],{},"        N30[Node: 30]\n",[3055,14739,14740],{"class":3057,"line":3797},[3055,14741,14742],{},"        V4 --> N30\n",[3055,14744,14745],{"class":3057,"line":3826},[3055,14746,14747],{},"        N30 -.Спільний.-> N20\n",[3055,14749,14750],{"class":3057,"line":3831},[3055,14751,14657],{},[3055,14753,14754],{"class":3057,"line":3836},[3055,14755,3116],{"emptyLinePlaceholder":3115},[3055,14757,14758],{"class":3057,"line":3842},[3055,14759,14760],{},"    style N10 fill:#3b82f6,stroke:#1d4ed8,color:#ffffff\n",[3055,14762,14763],{"class":3057,"line":3848},[3055,14764,14765],{},"    style N20 fill:#3b82f6,stroke:#1d4ed8,color:#ffffff\n",[3055,14767,14768],{"class":3057,"line":3854},[3055,14769,14770],{},"    style N30 fill:#3b82f6,stroke:#1d4ed8,color:#ffffff\n",[2964,14772,14773],{},[2977,14774,14775],{},"Що відбувається при Remove?",[3044,14777,14779],{"className":3046,"code":14778,"language":3049,"meta":3051,"style":3051},"var list = ImmutableList.Create(10, 20, 30, 40);\nvar newList = list.Remove(20);  // [10, 30, 40]\n\n// Створюється нова структура дерева БЕЗ вузла 20\n// Вузли 10, 30, 40 можуть бути спільними (залежно від балансування)\n",[2968,14780,14781,14813,14836,14840,14845],{"__ignoreMap":3051},[3055,14782,14783,14785,14787,14789,14791,14793,14795,14797,14799,14801,14803,14805,14807,14809,14811],{"class":3057,"line":3058},[3055,14784,3123],{"class":3122},[3055,14786,3127],{"class":3126},[3055,14788,3130],{"class":3069},[3055,14790,13645],{"class":3126},[3055,14792,3080],{"class":3069},[3055,14794,14232],{"class":3168},[3055,14796,3172],{"class":3069},[3055,14798,3181],{"class":3175},[3055,14800,2971],{"class":3069},[3055,14802,10321],{"class":3175},[3055,14804,2971],{"class":3069},[3055,14806,10326],{"class":3175},[3055,14808,2971],{"class":3069},[3055,14810,13865],{"class":3175},[3055,14812,3324],{"class":3069},[3055,14814,14815,14817,14820,14822,14824,14826,14828,14830,14832,14834],{"class":3057,"line":3073},[3055,14816,3123],{"class":3122},[3055,14818,14819],{"class":3126}," newList",[3055,14821,3130],{"class":3069},[3055,14823,3310],{"class":3126},[3055,14825,3080],{"class":3069},[3055,14827,13932],{"class":3168},[3055,14829,3172],{"class":3069},[3055,14831,10321],{"class":3175},[3055,14833,3266],{"class":3069},[3055,14835,14014],{"class":3156},[3055,14837,14838],{"class":3057,"line":3093},[3055,14839,3116],{"emptyLinePlaceholder":3115},[3055,14841,14842],{"class":3057,"line":3112},[3055,14843,14844],{"class":3156},"// Створюється нова структура дерева БЕЗ вузла 20\n",[3055,14846,14847],{"class":3057,"line":3119},[3055,14848,14849],{"class":3156},"// Вузли 10, 30, 40 можуть бути спільними (залежно від балансування)\n",[2964,14851,14852],{},[2977,14853,14854],{},"Hash Array Mapped Trie (HAMT) для ImmutableDictionary",[2964,14856,14857,14860,14861,14864],{},[2968,14858,14859],{},"ImmutableDictionary\u003CK,V>"," використовує ще складнішу структуру — ",[2977,14862,14863],{},"HAMT"," (Hash Array Mapped Trie). Це дерево де:",[3009,14866,14867,14870,14873],{},[3012,14868,14869],{},"Кожен рівень використовує частину hash code для навігації",[3012,14871,14872],{},"Structural sharing працює на рівні вузлів дерева",[3012,14874,14875],{},"Операції: O(log₃₂ n) — дуже швидкий логарифм!",[3044,14877,14880],{"className":14878,"code":14879,"language":3496},[3494],"Hash code: 0x1A2B3C4D\n           ││││││││\n           ││││││└┴─ Рівень 1: індекс 0x4D (77)\n           ││││└┴─── Рівень 2: індекс 0x3C (60)\n           ││└┴───── Рівень 3: індекс 0x2B (43)\n           └┴─────── Рівень 4: індекс 0x1A (26)\n",[2968,14881,14879],{"__ignoreMap":3051},[2964,14883,14884],{},[2977,14885,14886],{},"Чому O(log₃₂ n)?",[2964,14888,14889],{},"Кожен вузол HAMT має 32 дочірні вузли (5 біт hash code). Для 1 мільйона елементів:",[3044,14891,14894],{"className":14892,"code":14893,"language":3496},[3494],"log₃₂(1,000,000) ≈ 4 рівні\n",[2968,14895,14893],{"__ignoreMap":3051},[2964,14897,14898],{},"Тобто максимум 4 переходи для будь-якої операції!",[2964,14900,14901,3490],{},[2977,14902,14903],{},"Складність операцій",[3009,14905,14906,14921,14930],{},[3012,14907,14908,2971,14910,2971,14912,5292,14914,14917,14918,14920],{},[2968,14909,3249],{},[2968,14911,13932],{},[2968,14913,14078],{},[2977,14915,14916],{},"O(log n)"," (не O(1) як у ",[2968,14919,2983],{},", але не O(n)!)",[3012,14922,14923,14924,5292,14927,14929],{},"Індексація ",[2968,14925,14926],{},"[i]",[2977,14928,14916],{}," (не O(1)!)",[3012,14931,14932,14933,5292,14935,14938],{},"Ітерація ",[2968,14934,5957],{},[2977,14936,14937],{},"O(n)"," (як звичайний список)",[3032,14940,14942],{"id":14941},"immutablelistbuilder-ефективні-batch-операції","ImmutableList.Builder — Ефективні Batch Операції",[2964,14944,14945,14946,14949,14950,14953],{},"Якщо потрібно виконати ",[2977,14947,14948],{},"багато"," модифікацій підряд, використовуйте ",[2977,14951,14952],{},"Builder"," щоб уникнути створення проміжних колекцій:",[3044,14955,14958],{"className":3046,"code":14956,"filename":14957,"language":3049,"meta":3050,"style":3051},"using System.Collections.Immutable;\nusing System.Diagnostics;\n\n// ❌ ПОВІЛЬНО: кожен Add створює нову колекцію\nvar sw = Stopwatch.StartNew();\nvar list = ImmutableList\u003Cint>.Empty;\nfor (int i = 0; i \u003C 10000; i++)\n{\n    list = list.Add(i);  // 10,000 нових колекцій!\n}\nsw.Stop();\nConsole.WriteLine($\"Without builder: {sw.ElapsedMilliseconds}ms\");  // ~150ms\n\n// ✅ ШВИДКО: Builder накопичує зміни, потім створює фінальну колекцію\nsw.Restart();\nvar builder = ImmutableList.CreateBuilder\u003Cint>();\nfor (int i = 0; i \u003C 10000; i++)\n{\n    builder.Add(i);  // Модифікує mutable builder\n}\nvar finalList = builder.ToImmutable();  // Одна immutable колекція\nsw.Stop();\nConsole.WriteLine($\"With builder: {sw.ElapsedMilliseconds}ms\");  // ~5ms (в 30x швидше!)\n","ImmutableListBuilder.cs",[2968,14959,14960,14976,14988,14992,14997,15013,15033,15063,15067,15089,15093,15103,15133,15137,15142,15153,15175,15203,15207,15225,15229,15251,15261],{"__ignoreMap":3051},[3055,14961,14962,14964,14966,14968,14970,14972,14974],{"class":3057,"line":3058},[3055,14963,3062],{"class":3061},[3055,14965,3066],{"class":3065},[3055,14967,3080],{"class":3069},[3055,14969,3083],{"class":3065},[3055,14971,3080],{"class":3069},[3055,14973,13668],{"class":3065},[3055,14975,3070],{"class":3069},[3055,14977,14978,14980,14982,14984,14986],{"class":3057,"line":3073},[3055,14979,3062],{"class":3061},[3055,14981,3066],{"class":3065},[3055,14983,3080],{"class":3069},[3055,14985,7954],{"class":3065},[3055,14987,3070],{"class":3069},[3055,14989,14990],{"class":3057,"line":3093},[3055,14991,3116],{"emptyLinePlaceholder":3115},[3055,14993,14994],{"class":3057,"line":3112},[3055,14995,14996],{"class":3156},"// ❌ ПОВІЛЬНО: кожен Add створює нову колекцію\n",[3055,14998,14999,15001,15003,15005,15007,15009,15011],{"class":3057,"line":3119},[3055,15000,3123],{"class":3122},[3055,15002,8606],{"class":3126},[3055,15004,3130],{"class":3069},[3055,15006,8611],{"class":3126},[3055,15008,3080],{"class":3069},[3055,15010,8616],{"class":3168},[3055,15012,4071],{"class":3069},[3055,15014,15015,15017,15019,15021,15023,15025,15027,15029,15031],{"class":3057,"line":3148},[3055,15016,3123],{"class":3122},[3055,15018,3127],{"class":3126},[3055,15020,3130],{"class":3069},[3055,15022,13645],{"class":3126},[3055,15024,3139],{"class":3069},[3055,15026,3142],{"class":3122},[3055,15028,13556],{"class":3069},[3055,15030,13559],{"class":3126},[3055,15032,3070],{"class":3069},[3055,15034,15035,15038,15040,15042,15044,15046,15048,15050,15052,15054,15057,15059,15061],{"class":3057,"line":3153},[3055,15036,15037],{"class":3061},"for",[3055,15039,3204],{"class":3069},[3055,15041,3142],{"class":3122},[3055,15043,5444],{"class":3126},[3055,15045,3130],{"class":3069},[3055,15047,3176],{"class":3175},[3055,15049,3216],{"class":3069},[3055,15051,3186],{"class":3126},[3055,15053,3222],{"class":3069},[3055,15055,15056],{"class":3175},"10000",[3055,15058,3216],{"class":3069},[3055,15060,3186],{"class":3126},[3055,15062,3232],{"class":3069},[3055,15064,15065],{"class":3057,"line":3160},[3055,15066,3195],{"class":3069},[3055,15068,15069,15072,15074,15076,15078,15080,15082,15084,15086],{"class":3057,"line":3192},[3055,15070,15071],{"class":3126},"    list",[3055,15073,3130],{"class":3069},[3055,15075,3310],{"class":3126},[3055,15077,3080],{"class":3069},[3055,15079,3249],{"class":3168},[3055,15081,3172],{"class":3069},[3055,15083,3186],{"class":3126},[3055,15085,3266],{"class":3069},[3055,15087,15088],{"class":3156},"// 10,000 нових колекцій!\n",[3055,15090,15091],{"class":3057,"line":3198},[3055,15092,3484],{"class":3069},[3055,15094,15095,15097,15099,15101],{"class":3057,"line":3235},[3055,15096,8743],{"class":3126},[3055,15098,3080],{"class":3069},[3055,15100,8748],{"class":3168},[3055,15102,4071],{"class":3069},[3055,15104,15105,15107,15109,15111,15113,15116,15118,15120,15122,15124,15126,15128,15130],{"class":3057,"line":3241},[3055,15106,3292],{"class":3126},[3055,15108,3080],{"class":3069},[3055,15110,3297],{"class":3168},[3055,15112,3172],{"class":3069},[3055,15114,15115],{"class":3302},"$\"Without builder: ",[3055,15117,3307],{"class":3306},[3055,15119,8743],{"class":3126},[3055,15121,3080],{"class":3306},[3055,15123,8776],{"class":3126},[3055,15125,3318],{"class":3306},[3055,15127,8781],{"class":3302},[3055,15129,3266],{"class":3069},[3055,15131,15132],{"class":3156},"// ~150ms\n",[3055,15134,15135],{"class":3057,"line":3272},[3055,15136,3116],{"emptyLinePlaceholder":3115},[3055,15138,15139],{"class":3057,"line":3278},[3055,15140,15141],{"class":3156},"// ✅ ШВИДКО: Builder накопичує зміни, потім створює фінальну колекцію\n",[3055,15143,15144,15146,15148,15151],{"class":3057,"line":3284},[3055,15145,8743],{"class":3126},[3055,15147,3080],{"class":3069},[3055,15149,15150],{"class":3168},"Restart",[3055,15152,4071],{"class":3069},[3055,15154,15155,15157,15160,15162,15164,15166,15169,15171,15173],{"class":3057,"line":3289},[3055,15156,3123],{"class":3122},[3055,15158,15159],{"class":3126}," builder",[3055,15161,3130],{"class":3069},[3055,15163,13645],{"class":3126},[3055,15165,3080],{"class":3069},[3055,15167,15168],{"class":3168},"CreateBuilder",[3055,15170,3139],{"class":3069},[3055,15172,3142],{"class":3122},[3055,15174,3145],{"class":3069},[3055,15176,15177,15179,15181,15183,15185,15187,15189,15191,15193,15195,15197,15199,15201],{"class":3057,"line":3327},[3055,15178,15037],{"class":3061},[3055,15180,3204],{"class":3069},[3055,15182,3142],{"class":3122},[3055,15184,5444],{"class":3126},[3055,15186,3130],{"class":3069},[3055,15188,3176],{"class":3175},[3055,15190,3216],{"class":3069},[3055,15192,3186],{"class":3126},[3055,15194,3222],{"class":3069},[3055,15196,15056],{"class":3175},[3055,15198,3216],{"class":3069},[3055,15200,3186],{"class":3126},[3055,15202,3232],{"class":3069},[3055,15204,15205],{"class":3057,"line":3333},[3055,15206,3195],{"class":3069},[3055,15208,15209,15212,15214,15216,15218,15220,15222],{"class":3057,"line":3338},[3055,15210,15211],{"class":3126},"    builder",[3055,15213,3080],{"class":3069},[3055,15215,3249],{"class":3168},[3055,15217,3172],{"class":3069},[3055,15219,3186],{"class":3126},[3055,15221,3266],{"class":3069},[3055,15223,15224],{"class":3156},"// Модифікує mutable builder\n",[3055,15226,15227],{"class":3057,"line":3755},[3055,15228,3484],{"class":3069},[3055,15230,15231,15233,15236,15238,15241,15243,15246,15248],{"class":3057,"line":3760},[3055,15232,3123],{"class":3122},[3055,15234,15235],{"class":3126}," finalList",[3055,15237,3130],{"class":3069},[3055,15239,15240],{"class":3126},"builder",[3055,15242,3080],{"class":3069},[3055,15244,15245],{"class":3168},"ToImmutable",[3055,15247,5215],{"class":3069},[3055,15249,15250],{"class":3156},"// Одна immutable колекція\n",[3055,15252,15253,15255,15257,15259],{"class":3057,"line":3797},[3055,15254,8743],{"class":3126},[3055,15256,3080],{"class":3069},[3055,15258,8748],{"class":3168},[3055,15260,4071],{"class":3069},[3055,15262,15263,15265,15267,15269,15271,15274,15276,15278,15280,15282,15284,15286,15288],{"class":3057,"line":3826},[3055,15264,3292],{"class":3126},[3055,15266,3080],{"class":3069},[3055,15268,3297],{"class":3168},[3055,15270,3172],{"class":3069},[3055,15272,15273],{"class":3302},"$\"With builder: ",[3055,15275,3307],{"class":3306},[3055,15277,8743],{"class":3126},[3055,15279,3080],{"class":3306},[3055,15281,8776],{"class":3126},[3055,15283,3318],{"class":3306},[3055,15285,8781],{"class":3302},[3055,15287,3266],{"class":3069},[3055,15289,15290],{"class":3156},"// ~5ms (в 30x швидше!)\n",[2964,15292,15293,15296],{},[2977,15294,15295],{},"Pattern",": Використовуйте Builder для batch операцій, потім конвертуйте у immutable:",[3044,15298,15300],{"className":3046,"code":15299,"language":3049,"meta":3051,"style":3051},"var builder = ImmutableList.CreateBuilder\u003Cstring>();\nbuilder.Add(\"A\");\nbuilder.AddRange(new[] { \"B\", \"C\", \"D\" });\nbuilder.Remove(\"C\");\nvar immutableList = builder.ToImmutable();  // Фінальна immutable версія\n",[2968,15301,15302,15322,15336,15367,15381],{"__ignoreMap":3051},[3055,15303,15304,15306,15308,15310,15312,15314,15316,15318,15320],{"class":3057,"line":3058},[3055,15305,3123],{"class":3122},[3055,15307,15159],{"class":3126},[3055,15309,3130],{"class":3069},[3055,15311,13645],{"class":3126},[3055,15313,3080],{"class":3069},[3055,15315,15168],{"class":3168},[3055,15317,3139],{"class":3069},[3055,15319,3580],{"class":3122},[3055,15321,3145],{"class":3069},[3055,15323,15324,15326,15328,15330,15332,15334],{"class":3057,"line":3073},[3055,15325,15240],{"class":3126},[3055,15327,3080],{"class":3069},[3055,15329,3249],{"class":3168},[3055,15331,3172],{"class":3069},[3055,15333,10645],{"class":3302},[3055,15335,3324],{"class":3069},[3055,15337,15338,15340,15342,15345,15347,15349,15351,15354,15356,15359,15361,15364],{"class":3057,"line":3093},[3055,15339,15240],{"class":3126},[3055,15341,3080],{"class":3069},[3055,15343,15344],{"class":3168},"AddRange",[3055,15346,3172],{"class":3069},[3055,15348,3133],{"class":3122},[3055,15350,8082],{"class":3069},[3055,15352,15353],{"class":3302},"\"B\"",[3055,15355,2971],{"class":3069},[3055,15357,15358],{"class":3302},"\"C\"",[3055,15360,2971],{"class":3069},[3055,15362,15363],{"class":3302},"\"D\"",[3055,15365,15366],{"class":3069}," });\n",[3055,15368,15369,15371,15373,15375,15377,15379],{"class":3057,"line":3112},[3055,15370,15240],{"class":3126},[3055,15372,3080],{"class":3069},[3055,15374,13932],{"class":3168},[3055,15376,3172],{"class":3069},[3055,15378,15358],{"class":3302},[3055,15380,3324],{"class":3069},[3055,15382,15383,15385,15388,15390,15392,15394,15396,15398],{"class":3057,"line":3119},[3055,15384,3123],{"class":3122},[3055,15386,15387],{"class":3126}," immutableList",[3055,15389,3130],{"class":3069},[3055,15391,15240],{"class":3126},[3055,15393,3080],{"class":3069},[3055,15395,15245],{"class":3168},[3055,15397,5215],{"class":3069},[3055,15399,15400],{"class":3156},"// Фінальна immutable версія\n",[3032,15402,15404],{"id":15403},"immutabledictionarytkey-tvalue","ImmutableDictionary\u003CTKey, TValue>",[3044,15406,15409],{"className":3046,"code":15407,"filename":15408,"language":3049,"meta":3050,"style":3051},"using System.Collections.Immutable;\n\n// Створення порожнього словника\nvar dict1 = ImmutableDictionary\u003Cstring, int>.Empty;\n\n// Add створює нову колекцію\nvar dict2 = dict1.Add(\"apple\", 10);\nvar dict3 = dict2.Add(\"banana\", 20).Add(\"cherry\", 30);\n\nConsole.WriteLine($\"dict1.Count: {dict1.Count}\");  // 0\nConsole.WriteLine($\"dict3.Count: {dict3.Count}\");  // 3\n\n// Індексація (read-only)\nConsole.WriteLine($\"dict3[\\\"banana\\\"]: {dict3[\"banana\"]}\");  // 20\n\n// TryGetValue\nif (dict3.TryGetValue(\"apple\", out int value))\n{\n    Console.WriteLine($\"Found: {value}\");  // 10\n}\n\n// SetItem — \"змінити\" значення (створює нову колекцію)\nvar dict4 = dict3.SetItem(\"banana\", 999);\nConsole.WriteLine($\"dict3[\\\"banana\\\"]: {dict3[\"banana\"]}\");  // 20 (не змінився)\nConsole.WriteLine($\"dict4[\\\"banana\\\"]: {dict4[\"banana\"]}\");  // 999\n\n// Remove\nvar dict5 = dict4.Remove(\"cherry\");\nConsole.WriteLine($\"dict4.Count: {dict4.Count}\");  // 3\nConsole.WriteLine($\"dict5.Count: {dict5.Count}\");  // 2\n\n// SetItems — batch update\nvar updates = new Dictionary\u003Cstring, int>\n{\n    [\"apple\"] = 100,\n    [\"banana\"] = 200\n};\nvar dict6 = dict5.SetItems(updates);\nConsole.WriteLine($\"dict6[\\\"apple\\\"]: {dict6[\"apple\"]}\");  // 100\n","ImmutableDictionaryBasics.cs",[2968,15410,15411,15427,15431,15436,15461,15465,15470,15497,15537,15541,15570,15601,15605,15609,15649,15653,15658,15684,15688,15713,15717,15721,15726,15751,15788,15827,15831,15836,15857,15886,15916,15920,15925,15948,15952,15965,15976,15981,16004],{"__ignoreMap":3051},[3055,15412,15413,15415,15417,15419,15421,15423,15425],{"class":3057,"line":3058},[3055,15414,3062],{"class":3061},[3055,15416,3066],{"class":3065},[3055,15418,3080],{"class":3069},[3055,15420,3083],{"class":3065},[3055,15422,3080],{"class":3069},[3055,15424,13668],{"class":3065},[3055,15426,3070],{"class":3069},[3055,15428,15429],{"class":3057,"line":3073},[3055,15430,3116],{"emptyLinePlaceholder":3115},[3055,15432,15433],{"class":3057,"line":3093},[3055,15434,15435],{"class":3156},"// Створення порожнього словника\n",[3055,15437,15438,15440,15443,15445,15447,15449,15451,15453,15455,15457,15459],{"class":3057,"line":3112},[3055,15439,3123],{"class":3122},[3055,15441,15442],{"class":3126}," dict1",[3055,15444,3130],{"class":3069},[3055,15446,13545],{"class":3126},[3055,15448,3139],{"class":3069},[3055,15450,3580],{"class":3122},[3055,15452,2971],{"class":3069},[3055,15454,3142],{"class":3122},[3055,15456,13556],{"class":3069},[3055,15458,13559],{"class":3126},[3055,15460,3070],{"class":3069},[3055,15462,15463],{"class":3057,"line":3119},[3055,15464,3116],{"emptyLinePlaceholder":3115},[3055,15466,15467],{"class":3057,"line":3148},[3055,15468,15469],{"class":3156},"// Add створює нову колекцію\n",[3055,15471,15472,15474,15477,15479,15482,15484,15486,15488,15491,15493,15495],{"class":3057,"line":3153},[3055,15473,3123],{"class":3122},[3055,15475,15476],{"class":3126}," dict2",[3055,15478,3130],{"class":3069},[3055,15480,15481],{"class":3126},"dict1",[3055,15483,3080],{"class":3069},[3055,15485,3249],{"class":3168},[3055,15487,3172],{"class":3069},[3055,15489,15490],{"class":3302},"\"apple\"",[3055,15492,2971],{"class":3069},[3055,15494,3181],{"class":3175},[3055,15496,3324],{"class":3069},[3055,15498,15499,15501,15504,15506,15509,15511,15513,15515,15518,15520,15522,15524,15526,15528,15531,15533,15535],{"class":3057,"line":3160},[3055,15500,3123],{"class":3122},[3055,15502,15503],{"class":3126}," dict3",[3055,15505,3130],{"class":3069},[3055,15507,15508],{"class":3126},"dict2",[3055,15510,3080],{"class":3069},[3055,15512,3249],{"class":3168},[3055,15514,3172],{"class":3069},[3055,15516,15517],{"class":3302},"\"banana\"",[3055,15519,2971],{"class":3069},[3055,15521,10321],{"class":3175},[3055,15523,12874],{"class":3069},[3055,15525,3249],{"class":3168},[3055,15527,3172],{"class":3069},[3055,15529,15530],{"class":3302},"\"cherry\"",[3055,15532,2971],{"class":3069},[3055,15534,10326],{"class":3175},[3055,15536,3324],{"class":3069},[3055,15538,15539],{"class":3057,"line":3192},[3055,15540,3116],{"emptyLinePlaceholder":3115},[3055,15542,15543,15545,15547,15549,15551,15554,15556,15558,15560,15562,15564,15566,15568],{"class":3057,"line":3198},[3055,15544,3292],{"class":3126},[3055,15546,3080],{"class":3069},[3055,15548,3297],{"class":3168},[3055,15550,3172],{"class":3069},[3055,15552,15553],{"class":3302},"$\"dict1.Count: ",[3055,15555,3307],{"class":3306},[3055,15557,15481],{"class":3126},[3055,15559,3080],{"class":3306},[3055,15561,3315],{"class":3126},[3055,15563,3318],{"class":3306},[3055,15565,3321],{"class":3302},[3055,15567,3266],{"class":3069},[3055,15569,13731],{"class":3156},[3055,15571,15572,15574,15576,15578,15580,15583,15585,15588,15590,15592,15594,15596,15598],{"class":3057,"line":3235},[3055,15573,3292],{"class":3126},[3055,15575,3080],{"class":3069},[3055,15577,3297],{"class":3168},[3055,15579,3172],{"class":3069},[3055,15581,15582],{"class":3302},"$\"dict3.Count: ",[3055,15584,3307],{"class":3306},[3055,15586,15587],{"class":3126},"dict3",[3055,15589,3080],{"class":3306},[3055,15591,3315],{"class":3126},[3055,15593,3318],{"class":3306},[3055,15595,3321],{"class":3302},[3055,15597,3266],{"class":3069},[3055,15599,15600],{"class":3156},"// 3\n",[3055,15602,15603],{"class":3057,"line":3241},[3055,15604,3116],{"emptyLinePlaceholder":3115},[3055,15606,15607],{"class":3057,"line":3272},[3055,15608,14023],{"class":3156},[3055,15610,15611,15613,15615,15617,15619,15622,15625,15628,15630,15633,15635,15637,15639,15641,15643,15645,15647],{"class":3057,"line":3278},[3055,15612,3292],{"class":3126},[3055,15614,3080],{"class":3069},[3055,15616,3297],{"class":3168},[3055,15618,3172],{"class":3069},[3055,15620,15621],{"class":3302},"$\"dict3[",[3055,15623,15624],{"class":8093},"\\\"",[3055,15626,15627],{"class":3302},"banana",[3055,15629,15624],{"class":8093},[3055,15631,15632],{"class":3302},"]: ",[3055,15634,3307],{"class":3306},[3055,15636,15587],{"class":3126},[3055,15638,3454],{"class":3306},[3055,15640,15517],{"class":3302},[3055,15642,4807],{"class":3306},[3055,15644,3321],{"class":3302},[3055,15646,3266],{"class":3069},[3055,15648,14053],{"class":3156},[3055,15650,15651],{"class":3057,"line":3284},[3055,15652,3116],{"emptyLinePlaceholder":3115},[3055,15654,15655],{"class":3057,"line":3289},[3055,15656,15657],{"class":3156},"// TryGetValue\n",[3055,15659,15660,15662,15664,15666,15668,15670,15672,15674,15676,15678,15680,15682],{"class":3057,"line":3327},[3055,15661,4888],{"class":3061},[3055,15663,3204],{"class":3069},[3055,15665,15587],{"class":3126},[3055,15667,3080],{"class":3069},[3055,15669,4897],{"class":3168},[3055,15671,3172],{"class":3069},[3055,15673,15490],{"class":3302},[3055,15675,2971],{"class":3069},[3055,15677,4906],{"class":3122},[3055,15679,4909],{"class":3122},[3055,15681,4912],{"class":3126},[3055,15683,4915],{"class":3069},[3055,15685,15686],{"class":3057,"line":3333},[3055,15687,3195],{"class":3069},[3055,15689,15690,15692,15694,15696,15698,15700,15702,15704,15706,15708,15710],{"class":3057,"line":3338},[3055,15691,3763],{"class":3126},[3055,15693,3080],{"class":3069},[3055,15695,3297],{"class":3168},[3055,15697,3172],{"class":3069},[3055,15699,4932],{"class":3302},[3055,15701,3307],{"class":3306},[3055,15703,4937],{"class":3126},[3055,15705,3318],{"class":3306},[3055,15707,3321],{"class":3302},[3055,15709,3266],{"class":3069},[3055,15711,15712],{"class":3156},"// 10\n",[3055,15714,15715],{"class":3057,"line":3755},[3055,15716,3484],{"class":3069},[3055,15718,15719],{"class":3057,"line":3760},[3055,15720,3116],{"emptyLinePlaceholder":3115},[3055,15722,15723],{"class":3057,"line":3797},[3055,15724,15725],{"class":3156},"// SetItem — \"змінити\" значення (створює нову колекцію)\n",[3055,15727,15728,15730,15733,15735,15737,15739,15741,15743,15745,15747,15749],{"class":3057,"line":3826},[3055,15729,3123],{"class":3122},[3055,15731,15732],{"class":3126}," dict4",[3055,15734,3130],{"class":3069},[3055,15736,15587],{"class":3126},[3055,15738,3080],{"class":3069},[3055,15740,14078],{"class":3168},[3055,15742,3172],{"class":3069},[3055,15744,15517],{"class":3302},[3055,15746,2971],{"class":3069},[3055,15748,14087],{"class":3175},[3055,15750,3324],{"class":3069},[3055,15752,15753,15755,15757,15759,15761,15763,15765,15767,15769,15771,15773,15775,15777,15779,15781,15783,15785],{"class":3057,"line":3831},[3055,15754,3292],{"class":3126},[3055,15756,3080],{"class":3069},[3055,15758,3297],{"class":3168},[3055,15760,3172],{"class":3069},[3055,15762,15621],{"class":3302},[3055,15764,15624],{"class":8093},[3055,15766,15627],{"class":3302},[3055,15768,15624],{"class":8093},[3055,15770,15632],{"class":3302},[3055,15772,3307],{"class":3306},[3055,15774,15587],{"class":3126},[3055,15776,3454],{"class":3306},[3055,15778,15517],{"class":3302},[3055,15780,4807],{"class":3306},[3055,15782,3321],{"class":3302},[3055,15784,3266],{"class":3069},[3055,15786,15787],{"class":3156},"// 20 (не змінився)\n",[3055,15789,15790,15792,15794,15796,15798,15801,15803,15805,15807,15809,15811,15814,15816,15818,15820,15822,15824],{"class":3057,"line":3836},[3055,15791,3292],{"class":3126},[3055,15793,3080],{"class":3069},[3055,15795,3297],{"class":3168},[3055,15797,3172],{"class":3069},[3055,15799,15800],{"class":3302},"$\"dict4[",[3055,15802,15624],{"class":8093},[3055,15804,15627],{"class":3302},[3055,15806,15624],{"class":8093},[3055,15808,15632],{"class":3302},[3055,15810,3307],{"class":3306},[3055,15812,15813],{"class":3126},"dict4",[3055,15815,3454],{"class":3306},[3055,15817,15517],{"class":3302},[3055,15819,4807],{"class":3306},[3055,15821,3321],{"class":3302},[3055,15823,3266],{"class":3069},[3055,15825,15826],{"class":3156},"// 999\n",[3055,15828,15829],{"class":3057,"line":3842},[3055,15830,3116],{"emptyLinePlaceholder":3115},[3055,15832,15833],{"class":3057,"line":3848},[3055,15834,15835],{"class":3156},"// Remove\n",[3055,15837,15838,15840,15843,15845,15847,15849,15851,15853,15855],{"class":3057,"line":3854},[3055,15839,3123],{"class":3122},[3055,15841,15842],{"class":3126}," dict5",[3055,15844,3130],{"class":3069},[3055,15846,15813],{"class":3126},[3055,15848,3080],{"class":3069},[3055,15850,13932],{"class":3168},[3055,15852,3172],{"class":3069},[3055,15854,15530],{"class":3302},[3055,15856,3324],{"class":3069},[3055,15858,15859,15861,15863,15865,15867,15870,15872,15874,15876,15878,15880,15882,15884],{"class":3057,"line":4603},[3055,15860,3292],{"class":3126},[3055,15862,3080],{"class":3069},[3055,15864,3297],{"class":3168},[3055,15866,3172],{"class":3069},[3055,15868,15869],{"class":3302},"$\"dict4.Count: ",[3055,15871,3307],{"class":3306},[3055,15873,15813],{"class":3126},[3055,15875,3080],{"class":3306},[3055,15877,3315],{"class":3126},[3055,15879,3318],{"class":3306},[3055,15881,3321],{"class":3302},[3055,15883,3266],{"class":3069},[3055,15885,15600],{"class":3156},[3055,15887,15888,15890,15892,15894,15896,15899,15901,15904,15906,15908,15910,15912,15914],{"class":3057,"line":4609},[3055,15889,3292],{"class":3126},[3055,15891,3080],{"class":3069},[3055,15893,3297],{"class":3168},[3055,15895,3172],{"class":3069},[3055,15897,15898],{"class":3302},"$\"dict5.Count: ",[3055,15900,3307],{"class":3306},[3055,15902,15903],{"class":3126},"dict5",[3055,15905,3080],{"class":3306},[3055,15907,3315],{"class":3126},[3055,15909,3318],{"class":3306},[3055,15911,3321],{"class":3302},[3055,15913,3266],{"class":3069},[3055,15915,9356],{"class":3156},[3055,15917,15918],{"class":3057,"line":7082},[3055,15919,3116],{"emptyLinePlaceholder":3115},[3055,15921,15922],{"class":3057,"line":7095},[3055,15923,15924],{"class":3156},"// SetItems — batch update\n",[3055,15926,15927,15929,15932,15934,15936,15938,15940,15942,15944,15946],{"class":3057,"line":7104},[3055,15928,3123],{"class":3122},[3055,15930,15931],{"class":3126}," updates",[3055,15933,3130],{"class":3069},[3055,15935,3133],{"class":3122},[3055,15937,3575],{"class":3065},[3055,15939,3139],{"class":3069},[3055,15941,3580],{"class":3122},[3055,15943,2971],{"class":3069},[3055,15945,3142],{"class":3122},[3055,15947,10549],{"class":3069},[3055,15949,15950],{"class":3057,"line":7109},[3055,15951,3195],{"class":3069},[3055,15953,15954,15957,15959,15961,15963],{"class":3057,"line":7114},[3055,15955,15956],{"class":3069},"    [",[3055,15958,15490],{"class":3302},[3055,15960,3459],{"class":3069},[3055,15962,4693],{"class":3175},[3055,15964,5254],{"class":3069},[3055,15966,15967,15969,15971,15973],{"class":3057,"line":7152},[3055,15968,15956],{"class":3069},[3055,15970,15517],{"class":3302},[3055,15972,3459],{"class":3069},[3055,15974,15975],{"class":3175},"200\n",[3055,15977,15978],{"class":3057,"line":7157},[3055,15979,15980],{"class":3069},"};\n",[3055,15982,15983,15985,15988,15990,15992,15994,15997,15999,16002],{"class":3057,"line":7187},[3055,15984,3123],{"class":3122},[3055,15986,15987],{"class":3126}," dict6",[3055,15989,3130],{"class":3069},[3055,15991,15903],{"class":3126},[3055,15993,3080],{"class":3069},[3055,15995,15996],{"class":3168},"SetItems",[3055,15998,3172],{"class":3069},[3055,16000,16001],{"class":3126},"updates",[3055,16003,3324],{"class":3069},[3055,16005,16006,16008,16010,16012,16014,16017,16019,16022,16024,16026,16028,16031,16033,16035,16037,16039,16041],{"class":3057,"line":7211},[3055,16007,3292],{"class":3126},[3055,16009,3080],{"class":3069},[3055,16011,3297],{"class":3168},[3055,16013,3172],{"class":3069},[3055,16015,16016],{"class":3302},"$\"dict6[",[3055,16018,15624],{"class":8093},[3055,16020,16021],{"class":3302},"apple",[3055,16023,15624],{"class":8093},[3055,16025,15632],{"class":3302},[3055,16027,3307],{"class":3306},[3055,16029,16030],{"class":3126},"dict6",[3055,16032,3454],{"class":3306},[3055,16034,15490],{"class":3302},[3055,16036,4807],{"class":3306},[3055,16038,3321],{"class":3302},[3055,16040,3266],{"class":3069},[3055,16042,5315],{"class":3156},[3032,16044,16046,16047],{"id":16045},"immutablestack-та-immutablequeue","ImmutableStack",[3037,16048,16049,16050],{}," та ImmutableQueue",[3037,16051],{},[3044,16053,16056],{"className":3046,"code":16054,"filename":16055,"language":3049,"meta":3050,"style":3051},"using System.Collections.Immutable;\n\n// ImmutableStack — LIFO\nvar stack1 = ImmutableStack\u003Cint>.Empty;\nvar stack2 = stack1.Push(10).Push(20).Push(30);\n\nvar stack3 = stack2.Pop(out int top);\nConsole.WriteLine($\"Top: {top}\");  // 30\nConsole.WriteLine($\"stack2.Peek(): {stack2.Peek()}\");  // 30 (не змінився)\nConsole.WriteLine($\"stack3.Peek(): {stack3.Peek()}\");  // 20\n\n// ImmutableQueue — FIFO\nvar queue1 = ImmutableQueue\u003Cstring>.Empty;\nvar queue2 = queue1.Enqueue(\"A\").Enqueue(\"B\").Enqueue(\"C\");\n\nvar queue3 = queue2.Dequeue(out string first);\nConsole.WriteLine($\"First: {first}\");  // A\nConsole.WriteLine($\"queue2.Peek(): {queue2.Peek()}\");  // A (не змінився)\nConsole.WriteLine($\"queue3.Peek(): {queue3.Peek()}\");  // B\n","ImmutableStackQueue.cs",[2968,16057,16058,16074,16078,16083,16104,16142,16146,16174,16201,16233,16263,16267,16272,16294,16332,16336,16364,16391,16421],{"__ignoreMap":3051},[3055,16059,16060,16062,16064,16066,16068,16070,16072],{"class":3057,"line":3058},[3055,16061,3062],{"class":3061},[3055,16063,3066],{"class":3065},[3055,16065,3080],{"class":3069},[3055,16067,3083],{"class":3065},[3055,16069,3080],{"class":3069},[3055,16071,13668],{"class":3065},[3055,16073,3070],{"class":3069},[3055,16075,16076],{"class":3057,"line":3073},[3055,16077,3116],{"emptyLinePlaceholder":3115},[3055,16079,16080],{"class":3057,"line":3093},[3055,16081,16082],{"class":3156},"// ImmutableStack — LIFO\n",[3055,16084,16085,16087,16090,16092,16094,16096,16098,16100,16102],{"class":3057,"line":3112},[3055,16086,3123],{"class":3122},[3055,16088,16089],{"class":3126}," stack1",[3055,16091,3130],{"class":3069},[3055,16093,16046],{"class":3126},[3055,16095,3139],{"class":3069},[3055,16097,3142],{"class":3122},[3055,16099,13556],{"class":3069},[3055,16101,13559],{"class":3126},[3055,16103,3070],{"class":3069},[3055,16105,16106,16108,16111,16113,16116,16118,16120,16122,16124,16126,16128,16130,16132,16134,16136,16138,16140],{"class":3057,"line":3119},[3055,16107,3123],{"class":3122},[3055,16109,16110],{"class":3126}," stack2",[3055,16112,3130],{"class":3069},[3055,16114,16115],{"class":3126},"stack1",[3055,16117,3080],{"class":3069},[3055,16119,10053],{"class":3168},[3055,16121,3172],{"class":3069},[3055,16123,3181],{"class":3175},[3055,16125,12874],{"class":3069},[3055,16127,10053],{"class":3168},[3055,16129,3172],{"class":3069},[3055,16131,10321],{"class":3175},[3055,16133,12874],{"class":3069},[3055,16135,10053],{"class":3168},[3055,16137,3172],{"class":3069},[3055,16139,10326],{"class":3175},[3055,16141,3324],{"class":3069},[3055,16143,16144],{"class":3057,"line":3148},[3055,16145,3116],{"emptyLinePlaceholder":3115},[3055,16147,16148,16150,16153,16155,16158,16160,16163,16165,16167,16169,16172],{"class":3057,"line":3153},[3055,16149,3123],{"class":3122},[3055,16151,16152],{"class":3126}," stack3",[3055,16154,3130],{"class":3069},[3055,16156,16157],{"class":3126},"stack2",[3055,16159,3080],{"class":3069},[3055,16161,16162],{"class":3168},"Pop",[3055,16164,3172],{"class":3069},[3055,16166,4906],{"class":3122},[3055,16168,4909],{"class":3122},[3055,16170,16171],{"class":3126}," top",[3055,16173,3324],{"class":3069},[3055,16175,16176,16178,16180,16182,16184,16187,16189,16192,16194,16196,16198],{"class":3057,"line":3160},[3055,16177,3292],{"class":3126},[3055,16179,3080],{"class":3069},[3055,16181,3297],{"class":3168},[3055,16183,3172],{"class":3069},[3055,16185,16186],{"class":3302},"$\"Top: ",[3055,16188,3307],{"class":3306},[3055,16190,16191],{"class":3126},"top",[3055,16193,3318],{"class":3306},[3055,16195,3321],{"class":3302},[3055,16197,3266],{"class":3069},[3055,16199,16200],{"class":3156},"// 30\n",[3055,16202,16203,16205,16207,16209,16211,16214,16216,16218,16220,16223,16226,16228,16230],{"class":3057,"line":3192},[3055,16204,3292],{"class":3126},[3055,16206,3080],{"class":3069},[3055,16208,3297],{"class":3168},[3055,16210,3172],{"class":3069},[3055,16212,16213],{"class":3302},"$\"stack2.Peek(): ",[3055,16215,3307],{"class":3306},[3055,16217,16157],{"class":3126},[3055,16219,3080],{"class":3306},[3055,16221,16222],{"class":3168},"Peek",[3055,16224,16225],{"class":3306},"()}",[3055,16227,3321],{"class":3302},[3055,16229,3266],{"class":3069},[3055,16231,16232],{"class":3156},"// 30 (не змінився)\n",[3055,16234,16235,16237,16239,16241,16243,16246,16248,16251,16253,16255,16257,16259,16261],{"class":3057,"line":3198},[3055,16236,3292],{"class":3126},[3055,16238,3080],{"class":3069},[3055,16240,3297],{"class":3168},[3055,16242,3172],{"class":3069},[3055,16244,16245],{"class":3302},"$\"stack3.Peek(): ",[3055,16247,3307],{"class":3306},[3055,16249,16250],{"class":3126},"stack3",[3055,16252,3080],{"class":3306},[3055,16254,16222],{"class":3168},[3055,16256,16225],{"class":3306},[3055,16258,3321],{"class":3302},[3055,16260,3266],{"class":3069},[3055,16262,14053],{"class":3156},[3055,16264,16265],{"class":3057,"line":3235},[3055,16266,3116],{"emptyLinePlaceholder":3115},[3055,16268,16269],{"class":3057,"line":3241},[3055,16270,16271],{"class":3156},"// ImmutableQueue — FIFO\n",[3055,16273,16274,16276,16279,16281,16284,16286,16288,16290,16292],{"class":3057,"line":3272},[3055,16275,3123],{"class":3122},[3055,16277,16278],{"class":3126}," queue1",[3055,16280,3130],{"class":3069},[3055,16282,16283],{"class":3126},"ImmutableQueue",[3055,16285,3139],{"class":3069},[3055,16287,3580],{"class":3122},[3055,16289,13556],{"class":3069},[3055,16291,13559],{"class":3126},[3055,16293,3070],{"class":3069},[3055,16295,16296,16298,16301,16303,16306,16308,16310,16312,16314,16316,16318,16320,16322,16324,16326,16328,16330],{"class":3057,"line":3278},[3055,16297,3123],{"class":3122},[3055,16299,16300],{"class":3126}," queue2",[3055,16302,3130],{"class":3069},[3055,16304,16305],{"class":3126},"queue1",[3055,16307,3080],{"class":3069},[3055,16309,9095],{"class":3168},[3055,16311,3172],{"class":3069},[3055,16313,10645],{"class":3302},[3055,16315,12874],{"class":3069},[3055,16317,9095],{"class":3168},[3055,16319,3172],{"class":3069},[3055,16321,15353],{"class":3302},[3055,16323,12874],{"class":3069},[3055,16325,9095],{"class":3168},[3055,16327,3172],{"class":3069},[3055,16329,15358],{"class":3302},[3055,16331,3324],{"class":3069},[3055,16333,16334],{"class":3057,"line":3284},[3055,16335,3116],{"emptyLinePlaceholder":3115},[3055,16337,16338,16340,16343,16345,16348,16350,16353,16355,16357,16359,16362],{"class":3057,"line":3289},[3055,16339,3123],{"class":3122},[3055,16341,16342],{"class":3126}," queue3",[3055,16344,3130],{"class":3069},[3055,16346,16347],{"class":3126},"queue2",[3055,16349,3080],{"class":3069},[3055,16351,16352],{"class":3168},"Dequeue",[3055,16354,3172],{"class":3069},[3055,16356,4906],{"class":3122},[3055,16358,9806],{"class":3122},[3055,16360,16361],{"class":3126}," first",[3055,16363,3324],{"class":3069},[3055,16365,16366,16368,16370,16372,16374,16377,16379,16382,16384,16386,16388],{"class":3057,"line":3327},[3055,16367,3292],{"class":3126},[3055,16369,3080],{"class":3069},[3055,16371,3297],{"class":3168},[3055,16373,3172],{"class":3069},[3055,16375,16376],{"class":3302},"$\"First: ",[3055,16378,3307],{"class":3306},[3055,16380,16381],{"class":3126},"first",[3055,16383,3318],{"class":3306},[3055,16385,3321],{"class":3302},[3055,16387,3266],{"class":3069},[3055,16389,16390],{"class":3156},"// A\n",[3055,16392,16393,16395,16397,16399,16401,16404,16406,16408,16410,16412,16414,16416,16418],{"class":3057,"line":3333},[3055,16394,3292],{"class":3126},[3055,16396,3080],{"class":3069},[3055,16398,3297],{"class":3168},[3055,16400,3172],{"class":3069},[3055,16402,16403],{"class":3302},"$\"queue2.Peek(): ",[3055,16405,3307],{"class":3306},[3055,16407,16347],{"class":3126},[3055,16409,3080],{"class":3306},[3055,16411,16222],{"class":3168},[3055,16413,16225],{"class":3306},[3055,16415,3321],{"class":3302},[3055,16417,3266],{"class":3069},[3055,16419,16420],{"class":3156},"// A (не змінився)\n",[3055,16422,16423,16425,16427,16429,16431,16434,16436,16439,16441,16443,16445,16447,16449],{"class":3057,"line":3338},[3055,16424,3292],{"class":3126},[3055,16426,3080],{"class":3069},[3055,16428,3297],{"class":3168},[3055,16430,3172],{"class":3069},[3055,16432,16433],{"class":3302},"$\"queue3.Peek(): ",[3055,16435,3307],{"class":3306},[3055,16437,16438],{"class":3126},"queue3",[3055,16440,3080],{"class":3306},[3055,16442,16222],{"class":3168},[3055,16444,16225],{"class":3306},[3055,16446,3321],{"class":3302},[3055,16448,3266],{"class":3069},[3055,16450,16451],{"class":3156},"// B\n",[3032,16453,16455,16456],{"id":16454},"immutablehashset-та-immutablesortedset","ImmutableHashSet",[3037,16457,16458,16459],{}," та ImmutableSortedSet",[3037,16460],{},[2964,16462,16463],{},"Immutable колекції також включають множини (sets) для зберігання унікальних елементів.",[3044,16465,16468],{"className":3046,"code":16466,"filename":16467,"language":3049,"meta":3050,"style":3051},"using System.Collections.Immutable;\n\n// ImmutableHashSet — неупорядкована множина\nvar set1 = ImmutableHashSet\u003Cstring>.Empty;\nvar set2 = set1.Add(\"apple\").Add(\"banana\").Add(\"cherry\");\nvar set3 = set2.Add(\"apple\");  // Дублікат — не додається\n\nConsole.WriteLine($\"set2.Count: {set2.Count}\");  // 3\nConsole.WriteLine($\"set3.Count: {set3.Count}\");  // 3 (не змінився)\n\n// Contains — перевірка наявності\nConsole.WriteLine($\"Contains 'banana': {set3.Contains(\"banana\")}\");  // true\n\n// Union, Intersect, Except — операції над множинами\nvar setA = ImmutableHashSet.Create(\"a\", \"b\", \"c\");\nvar setB = ImmutableHashSet.Create(\"b\", \"c\", \"d\");\n\nvar union = setA.Union(setB);        // [a, b, c, d]\nvar intersect = setA.Intersect(setB); // [b, c]\nvar except = setA.Except(setB);       // [a]\n\nConsole.WriteLine($\"Union: [{string.Join(\", \", union)}]\");\nConsole.WriteLine($\"Intersect: [{string.Join(\", \", intersect)}]\");\nConsole.WriteLine($\"Except: [{string.Join(\", \", except)}]\");\n\n// ImmutableSortedSet — упорядкована множина\nvar sorted1 = ImmutableSortedSet\u003Cint>.Empty;\nvar sorted2 = sorted1.Add(30).Add(10).Add(20);\n\nConsole.WriteLine($\"Sorted: [{string.Join(\", \", sorted2)}]\");  // [10, 20, 30]\n","ImmutableSets.cs",[2968,16469,16470,16486,16490,16495,16516,16554,16579,16583,16612,16643,16647,16652,16685,16689,16694,16726,16756,16760,16788,16814,16840,16844,16880,16916,16952,16956,16961,16983,17021,17025],{"__ignoreMap":3051},[3055,16471,16472,16474,16476,16478,16480,16482,16484],{"class":3057,"line":3058},[3055,16473,3062],{"class":3061},[3055,16475,3066],{"class":3065},[3055,16477,3080],{"class":3069},[3055,16479,3083],{"class":3065},[3055,16481,3080],{"class":3069},[3055,16483,13668],{"class":3065},[3055,16485,3070],{"class":3069},[3055,16487,16488],{"class":3057,"line":3073},[3055,16489,3116],{"emptyLinePlaceholder":3115},[3055,16491,16492],{"class":3057,"line":3093},[3055,16493,16494],{"class":3156},"// ImmutableHashSet — неупорядкована множина\n",[3055,16496,16497,16499,16502,16504,16506,16508,16510,16512,16514],{"class":3057,"line":3112},[3055,16498,3123],{"class":3122},[3055,16500,16501],{"class":3126}," set1",[3055,16503,3130],{"class":3069},[3055,16505,16455],{"class":3126},[3055,16507,3139],{"class":3069},[3055,16509,3580],{"class":3122},[3055,16511,13556],{"class":3069},[3055,16513,13559],{"class":3126},[3055,16515,3070],{"class":3069},[3055,16517,16518,16520,16523,16525,16528,16530,16532,16534,16536,16538,16540,16542,16544,16546,16548,16550,16552],{"class":3057,"line":3119},[3055,16519,3123],{"class":3122},[3055,16521,16522],{"class":3126}," set2",[3055,16524,3130],{"class":3069},[3055,16526,16527],{"class":3126},"set1",[3055,16529,3080],{"class":3069},[3055,16531,3249],{"class":3168},[3055,16533,3172],{"class":3069},[3055,16535,15490],{"class":3302},[3055,16537,12874],{"class":3069},[3055,16539,3249],{"class":3168},[3055,16541,3172],{"class":3069},[3055,16543,15517],{"class":3302},[3055,16545,12874],{"class":3069},[3055,16547,3249],{"class":3168},[3055,16549,3172],{"class":3069},[3055,16551,15530],{"class":3302},[3055,16553,3324],{"class":3069},[3055,16555,16556,16558,16561,16563,16566,16568,16570,16572,16574,16576],{"class":3057,"line":3148},[3055,16557,3123],{"class":3122},[3055,16559,16560],{"class":3126}," set3",[3055,16562,3130],{"class":3069},[3055,16564,16565],{"class":3126},"set2",[3055,16567,3080],{"class":3069},[3055,16569,3249],{"class":3168},[3055,16571,3172],{"class":3069},[3055,16573,15490],{"class":3302},[3055,16575,3266],{"class":3069},[3055,16577,16578],{"class":3156},"// Дублікат — не додається\n",[3055,16580,16581],{"class":3057,"line":3153},[3055,16582,3116],{"emptyLinePlaceholder":3115},[3055,16584,16585,16587,16589,16591,16593,16596,16598,16600,16602,16604,16606,16608,16610],{"class":3057,"line":3160},[3055,16586,3292],{"class":3126},[3055,16588,3080],{"class":3069},[3055,16590,3297],{"class":3168},[3055,16592,3172],{"class":3069},[3055,16594,16595],{"class":3302},"$\"set2.Count: ",[3055,16597,3307],{"class":3306},[3055,16599,16565],{"class":3126},[3055,16601,3080],{"class":3306},[3055,16603,3315],{"class":3126},[3055,16605,3318],{"class":3306},[3055,16607,3321],{"class":3302},[3055,16609,3266],{"class":3069},[3055,16611,15600],{"class":3156},[3055,16613,16614,16616,16618,16620,16622,16625,16627,16630,16632,16634,16636,16638,16640],{"class":3057,"line":3192},[3055,16615,3292],{"class":3126},[3055,16617,3080],{"class":3069},[3055,16619,3297],{"class":3168},[3055,16621,3172],{"class":3069},[3055,16623,16624],{"class":3302},"$\"set3.Count: ",[3055,16626,3307],{"class":3306},[3055,16628,16629],{"class":3126},"set3",[3055,16631,3080],{"class":3306},[3055,16633,3315],{"class":3126},[3055,16635,3318],{"class":3306},[3055,16637,3321],{"class":3302},[3055,16639,3266],{"class":3069},[3055,16641,16642],{"class":3156},"// 3 (не змінився)\n",[3055,16644,16645],{"class":3057,"line":3198},[3055,16646,3116],{"emptyLinePlaceholder":3115},[3055,16648,16649],{"class":3057,"line":3235},[3055,16650,16651],{"class":3156},"// Contains — перевірка наявності\n",[3055,16653,16654,16656,16658,16660,16662,16665,16667,16669,16671,16673,16675,16677,16679,16681,16683],{"class":3057,"line":3241},[3055,16655,3292],{"class":3126},[3055,16657,3080],{"class":3069},[3055,16659,3297],{"class":3168},[3055,16661,3172],{"class":3069},[3055,16663,16664],{"class":3302},"$\"Contains 'banana': ",[3055,16666,3307],{"class":3306},[3055,16668,16629],{"class":3126},[3055,16670,3080],{"class":3306},[3055,16672,11753],{"class":3168},[3055,16674,3172],{"class":3306},[3055,16676,15517],{"class":3302},[3055,16678,8726],{"class":3306},[3055,16680,3321],{"class":3302},[3055,16682,3266],{"class":3069},[3055,16684,4722],{"class":3156},[3055,16686,16687],{"class":3057,"line":3272},[3055,16688,3116],{"emptyLinePlaceholder":3115},[3055,16690,16691],{"class":3057,"line":3278},[3055,16692,16693],{"class":3156},"// Union, Intersect, Except — операції над множинами\n",[3055,16695,16696,16698,16701,16703,16705,16707,16709,16711,16714,16716,16719,16721,16724],{"class":3057,"line":3284},[3055,16697,3123],{"class":3122},[3055,16699,16700],{"class":3126}," setA",[3055,16702,3130],{"class":3069},[3055,16704,16455],{"class":3126},[3055,16706,3080],{"class":3069},[3055,16708,14232],{"class":3168},[3055,16710,3172],{"class":3069},[3055,16712,16713],{"class":3302},"\"a\"",[3055,16715,2971],{"class":3069},[3055,16717,16718],{"class":3302},"\"b\"",[3055,16720,2971],{"class":3069},[3055,16722,16723],{"class":3302},"\"c\"",[3055,16725,3324],{"class":3069},[3055,16727,16728,16730,16733,16735,16737,16739,16741,16743,16745,16747,16749,16751,16754],{"class":3057,"line":3289},[3055,16729,3123],{"class":3122},[3055,16731,16732],{"class":3126}," setB",[3055,16734,3130],{"class":3069},[3055,16736,16455],{"class":3126},[3055,16738,3080],{"class":3069},[3055,16740,14232],{"class":3168},[3055,16742,3172],{"class":3069},[3055,16744,16718],{"class":3302},[3055,16746,2971],{"class":3069},[3055,16748,16723],{"class":3302},[3055,16750,2971],{"class":3069},[3055,16752,16753],{"class":3302},"\"d\"",[3055,16755,3324],{"class":3069},[3055,16757,16758],{"class":3057,"line":3327},[3055,16759,3116],{"emptyLinePlaceholder":3115},[3055,16761,16762,16764,16767,16769,16772,16774,16777,16779,16782,16785],{"class":3057,"line":3333},[3055,16763,3123],{"class":3122},[3055,16765,16766],{"class":3126}," union",[3055,16768,3130],{"class":3069},[3055,16770,16771],{"class":3126},"setA",[3055,16773,3080],{"class":3069},[3055,16775,16776],{"class":3168},"Union",[3055,16778,3172],{"class":3069},[3055,16780,16781],{"class":3126},"setB",[3055,16783,16784],{"class":3069},");        ",[3055,16786,16787],{"class":3156},"// [a, b, c, d]\n",[3055,16789,16790,16792,16795,16797,16799,16801,16804,16806,16808,16811],{"class":3057,"line":3338},[3055,16791,3123],{"class":3122},[3055,16793,16794],{"class":3126}," intersect",[3055,16796,3130],{"class":3069},[3055,16798,16771],{"class":3126},[3055,16800,3080],{"class":3069},[3055,16802,16803],{"class":3168},"Intersect",[3055,16805,3172],{"class":3069},[3055,16807,16781],{"class":3126},[3055,16809,16810],{"class":3069},"); ",[3055,16812,16813],{"class":3156},"// [b, c]\n",[3055,16815,16816,16818,16821,16823,16825,16827,16830,16832,16834,16837],{"class":3057,"line":3755},[3055,16817,3123],{"class":3122},[3055,16819,16820],{"class":3126}," except",[3055,16822,3130],{"class":3069},[3055,16824,16771],{"class":3126},[3055,16826,3080],{"class":3069},[3055,16828,16829],{"class":3168},"Except",[3055,16831,3172],{"class":3069},[3055,16833,16781],{"class":3126},[3055,16835,16836],{"class":3069},");       ",[3055,16838,16839],{"class":3156},"// [a]\n",[3055,16841,16842],{"class":3057,"line":3760},[3055,16843,3116],{"emptyLinePlaceholder":3115},[3055,16845,16846,16848,16850,16852,16854,16857,16859,16861,16863,16865,16867,16869,16871,16874,16876,16878],{"class":3057,"line":3797},[3055,16847,3292],{"class":3126},[3055,16849,3080],{"class":3069},[3055,16851,3297],{"class":3168},[3055,16853,3172],{"class":3069},[3055,16855,16856],{"class":3302},"$\"Union: [",[3055,16858,3307],{"class":3306},[3055,16860,3580],{"class":3122},[3055,16862,3080],{"class":3306},[3055,16864,10429],{"class":3168},[3055,16866,3172],{"class":3306},[3055,16868,10434],{"class":3302},[3055,16870,2971],{"class":3306},[3055,16872,16873],{"class":3126},"union",[3055,16875,8726],{"class":3306},[3055,16877,13902],{"class":3302},[3055,16879,3324],{"class":3069},[3055,16881,16882,16884,16886,16888,16890,16893,16895,16897,16899,16901,16903,16905,16907,16910,16912,16914],{"class":3057,"line":3826},[3055,16883,3292],{"class":3126},[3055,16885,3080],{"class":3069},[3055,16887,3297],{"class":3168},[3055,16889,3172],{"class":3069},[3055,16891,16892],{"class":3302},"$\"Intersect: [",[3055,16894,3307],{"class":3306},[3055,16896,3580],{"class":3122},[3055,16898,3080],{"class":3306},[3055,16900,10429],{"class":3168},[3055,16902,3172],{"class":3306},[3055,16904,10434],{"class":3302},[3055,16906,2971],{"class":3306},[3055,16908,16909],{"class":3126},"intersect",[3055,16911,8726],{"class":3306},[3055,16913,13902],{"class":3302},[3055,16915,3324],{"class":3069},[3055,16917,16918,16920,16922,16924,16926,16929,16931,16933,16935,16937,16939,16941,16943,16946,16948,16950],{"class":3057,"line":3831},[3055,16919,3292],{"class":3126},[3055,16921,3080],{"class":3069},[3055,16923,3297],{"class":3168},[3055,16925,3172],{"class":3069},[3055,16927,16928],{"class":3302},"$\"Except: [",[3055,16930,3307],{"class":3306},[3055,16932,3580],{"class":3122},[3055,16934,3080],{"class":3306},[3055,16936,10429],{"class":3168},[3055,16938,3172],{"class":3306},[3055,16940,10434],{"class":3302},[3055,16942,2971],{"class":3306},[3055,16944,16945],{"class":3126},"except",[3055,16947,8726],{"class":3306},[3055,16949,13902],{"class":3302},[3055,16951,3324],{"class":3069},[3055,16953,16954],{"class":3057,"line":3836},[3055,16955,3116],{"emptyLinePlaceholder":3115},[3055,16957,16958],{"class":3057,"line":3842},[3055,16959,16960],{"class":3156},"// ImmutableSortedSet — упорядкована множина\n",[3055,16962,16963,16965,16968,16970,16973,16975,16977,16979,16981],{"class":3057,"line":3848},[3055,16964,3123],{"class":3122},[3055,16966,16967],{"class":3126}," sorted1",[3055,16969,3130],{"class":3069},[3055,16971,16972],{"class":3126},"ImmutableSortedSet",[3055,16974,3139],{"class":3069},[3055,16976,3142],{"class":3122},[3055,16978,13556],{"class":3069},[3055,16980,13559],{"class":3126},[3055,16982,3070],{"class":3069},[3055,16984,16985,16987,16990,16992,16995,16997,16999,17001,17003,17005,17007,17009,17011,17013,17015,17017,17019],{"class":3057,"line":3854},[3055,16986,3123],{"class":3122},[3055,16988,16989],{"class":3126}," sorted2",[3055,16991,3130],{"class":3069},[3055,16993,16994],{"class":3126},"sorted1",[3055,16996,3080],{"class":3069},[3055,16998,3249],{"class":3168},[3055,17000,3172],{"class":3069},[3055,17002,10326],{"class":3175},[3055,17004,12874],{"class":3069},[3055,17006,3249],{"class":3168},[3055,17008,3172],{"class":3069},[3055,17010,3181],{"class":3175},[3055,17012,12874],{"class":3069},[3055,17014,3249],{"class":3168},[3055,17016,3172],{"class":3069},[3055,17018,10321],{"class":3175},[3055,17020,3324],{"class":3069},[3055,17022,17023],{"class":3057,"line":4603},[3055,17024,3116],{"emptyLinePlaceholder":3115},[3055,17026,17027,17029,17031,17033,17035,17038,17040,17042,17044,17046,17048,17050,17052,17055,17057,17059,17061],{"class":3057,"line":4609},[3055,17028,3292],{"class":3126},[3055,17030,3080],{"class":3069},[3055,17032,3297],{"class":3168},[3055,17034,3172],{"class":3069},[3055,17036,17037],{"class":3302},"$\"Sorted: [",[3055,17039,3307],{"class":3306},[3055,17041,3580],{"class":3122},[3055,17043,3080],{"class":3306},[3055,17045,10429],{"class":3168},[3055,17047,3172],{"class":3306},[3055,17049,10434],{"class":3302},[3055,17051,2971],{"class":3306},[3055,17053,17054],{"class":3126},"sorted2",[3055,17056,8726],{"class":3306},[3055,17058,13902],{"class":3302},[3055,17060,3266],{"class":3069},[3055,17062,14609],{"class":3156},[2964,17064,17065,3490],{},[2977,17066,4819],{},[3009,17068,17069,17075],{},[3012,17070,17071,17074],{},[2968,17072,17073],{},"ImmutableHashSet\u003CT>"," — коли потрібна швидка перевірка наявності (O(log n)) та порядок не важливий",[3012,17076,17077,17080],{},[2968,17078,17079],{},"ImmutableSortedSet\u003CT>"," — коли потрібен відсортований порядок елементів",[3032,17082,17084,17085],{"id":17083},"immutablearray-спеціальний-випадок","ImmutableArray",[3037,17086,17087],{}," — Спеціальний Випадок",[2964,17089,17090,9448,17093,17096,17097,3080],{},[2968,17091,17092],{},"ImmutableArray\u003CT>",[2977,17094,17095],{},"struct"," (не class!) що обгортає звичайний масив. На відміну від інших immutable колекцій, він ",[2977,17098,17099],{},"НЕ використовує structural sharing",[3044,17101,17104],{"className":3046,"code":17102,"filename":17103,"language":3049,"meta":3050,"style":3051},"using System.Collections.Immutable;\n\n// Створення з елементів\nvar array1 = ImmutableArray.Create(1, 2, 3, 4, 5);\n\n// Індексація — O(1) (швидше ніж ImmutableList!)\nConsole.WriteLine($\"array1[2]: {array1[2]}\");  // 3\n\n// \"Модифікація\" створює НОВИЙ масив (копіює всі елементи!)\nvar array2 = array1.Add(6);  // O(n) — копіює весь масив!\n\n// SetItem — також O(n)\nvar array3 = array1.SetItem(2, 999);\n\nConsole.WriteLine($\"array1: [{string.Join(\", \", array1)}]\");  // [1, 2, 3, 4, 5]\nConsole.WriteLine($\"array3: [{string.Join(\", \", array3)}]\");  // [1, 2, 999, 4, 5]\n","ImmutableArrayBasics.cs",[2968,17105,17106,17122,17126,17131,17168,17172,17177,17207,17211,17216,17240,17244,17249,17274,17278,17315],{"__ignoreMap":3051},[3055,17107,17108,17110,17112,17114,17116,17118,17120],{"class":3057,"line":3058},[3055,17109,3062],{"class":3061},[3055,17111,3066],{"class":3065},[3055,17113,3080],{"class":3069},[3055,17115,3083],{"class":3065},[3055,17117,3080],{"class":3069},[3055,17119,13668],{"class":3065},[3055,17121,3070],{"class":3069},[3055,17123,17124],{"class":3057,"line":3073},[3055,17125,3116],{"emptyLinePlaceholder":3115},[3055,17127,17128],{"class":3057,"line":3093},[3055,17129,17130],{"class":3156},"// Створення з елементів\n",[3055,17132,17133,17135,17138,17140,17142,17144,17146,17148,17150,17152,17154,17156,17158,17160,17162,17164,17166],{"class":3057,"line":3112},[3055,17134,3123],{"class":3122},[3055,17136,17137],{"class":3126}," array1",[3055,17139,3130],{"class":3069},[3055,17141,17084],{"class":3126},[3055,17143,3080],{"class":3069},[3055,17145,14232],{"class":3168},[3055,17147,3172],{"class":3069},[3055,17149,3433],{"class":3175},[3055,17151,2971],{"class":3069},[3055,17153,5278],{"class":3175},[3055,17155,2971],{"class":3069},[3055,17157,9223],{"class":3175},[3055,17159,2971],{"class":3069},[3055,17161,14249],{"class":3175},[3055,17163,2971],{"class":3069},[3055,17165,11550],{"class":3175},[3055,17167,3324],{"class":3069},[3055,17169,17170],{"class":3057,"line":3119},[3055,17171,3116],{"emptyLinePlaceholder":3115},[3055,17173,17174],{"class":3057,"line":3148},[3055,17175,17176],{"class":3156},"// Індексація — O(1) (швидше ніж ImmutableList!)\n",[3055,17178,17179,17181,17183,17185,17187,17190,17192,17195,17197,17199,17201,17203,17205],{"class":3057,"line":3153},[3055,17180,3292],{"class":3126},[3055,17182,3080],{"class":3069},[3055,17184,3297],{"class":3168},[3055,17186,3172],{"class":3069},[3055,17188,17189],{"class":3302},"$\"array1[2]: ",[3055,17191,3307],{"class":3306},[3055,17193,17194],{"class":3126},"array1",[3055,17196,3454],{"class":3306},[3055,17198,5278],{"class":3175},[3055,17200,4807],{"class":3306},[3055,17202,3321],{"class":3302},[3055,17204,3266],{"class":3069},[3055,17206,15600],{"class":3156},[3055,17208,17209],{"class":3057,"line":3160},[3055,17210,3116],{"emptyLinePlaceholder":3115},[3055,17212,17213],{"class":3057,"line":3192},[3055,17214,17215],{"class":3156},"// \"Модифікація\" створює НОВИЙ масив (копіює всі елементи!)\n",[3055,17217,17218,17220,17223,17225,17227,17229,17231,17233,17235,17237],{"class":3057,"line":3198},[3055,17219,3123],{"class":3122},[3055,17221,17222],{"class":3126}," array2",[3055,17224,3130],{"class":3069},[3055,17226,17194],{"class":3126},[3055,17228,3080],{"class":3069},[3055,17230,3249],{"class":3168},[3055,17232,3172],{"class":3069},[3055,17234,14277],{"class":3175},[3055,17236,3266],{"class":3069},[3055,17238,17239],{"class":3156},"// O(n) — копіює весь масив!\n",[3055,17241,17242],{"class":3057,"line":3235},[3055,17243,3116],{"emptyLinePlaceholder":3115},[3055,17245,17246],{"class":3057,"line":3241},[3055,17247,17248],{"class":3156},"// SetItem — також O(n)\n",[3055,17250,17251,17253,17256,17258,17260,17262,17264,17266,17268,17270,17272],{"class":3057,"line":3272},[3055,17252,3123],{"class":3122},[3055,17254,17255],{"class":3126}," array3",[3055,17257,3130],{"class":3069},[3055,17259,17194],{"class":3126},[3055,17261,3080],{"class":3069},[3055,17263,14078],{"class":3168},[3055,17265,3172],{"class":3069},[3055,17267,5278],{"class":3175},[3055,17269,2971],{"class":3069},[3055,17271,14087],{"class":3175},[3055,17273,3324],{"class":3069},[3055,17275,17276],{"class":3057,"line":3278},[3055,17277,3116],{"emptyLinePlaceholder":3115},[3055,17279,17280,17282,17284,17286,17288,17291,17293,17295,17297,17299,17301,17303,17305,17307,17309,17311,17313],{"class":3057,"line":3284},[3055,17281,3292],{"class":3126},[3055,17283,3080],{"class":3069},[3055,17285,3297],{"class":3168},[3055,17287,3172],{"class":3069},[3055,17289,17290],{"class":3302},"$\"array1: [",[3055,17292,3307],{"class":3306},[3055,17294,3580],{"class":3122},[3055,17296,3080],{"class":3306},[3055,17298,10429],{"class":3168},[3055,17300,3172],{"class":3306},[3055,17302,10434],{"class":3302},[3055,17304,2971],{"class":3306},[3055,17306,17194],{"class":3126},[3055,17308,8726],{"class":3306},[3055,17310,13902],{"class":3302},[3055,17312,3266],{"class":3069},[3055,17314,14258],{"class":3156},[3055,17316,17317,17319,17321,17323,17325,17328,17330,17332,17334,17336,17338,17340,17342,17345,17347,17349,17351],{"class":3057,"line":3289},[3055,17318,3292],{"class":3126},[3055,17320,3080],{"class":3069},[3055,17322,3297],{"class":3168},[3055,17324,3172],{"class":3069},[3055,17326,17327],{"class":3302},"$\"array3: [",[3055,17329,3307],{"class":3306},[3055,17331,3580],{"class":3122},[3055,17333,3080],{"class":3306},[3055,17335,10429],{"class":3168},[3055,17337,3172],{"class":3306},[3055,17339,10434],{"class":3302},[3055,17341,2971],{"class":3306},[3055,17343,17344],{"class":3126},"array3",[3055,17346,8726],{"class":3306},[3055,17348,13902],{"class":3302},[3055,17350,3266],{"class":3069},[3055,17352,17353],{"class":3156},"// [1, 2, 999, 4, 5]\n",[2964,17355,17356,3490],{},[2977,17357,17358],{},"Коли використовувати ImmutableArray",[3009,17360,17361,17368,17371],{},[3012,17362,17363,17364,17367],{},"Колекція ",[2977,17365,17366],{},"рідко змінюється"," (або взагалі не змінюється після створення)",[3012,17369,17370],{},"Потрібен швидкий доступ за індексом O(1)",[3012,17372,17373],{},"Розмір колекції невеликий (до кількох тисяч елементів)",[2964,17375,17376,3490],{},[2977,17377,17378],{},"Коли НЕ використовувати",[3009,17380,17381,17387],{},[3012,17382,17383,17384,17386],{},"Часті модифікації → ",[2968,17385,14202],{}," (O(log n) замість O(n))",[3012,17388,17389],{},"Великі колекції з частими змінами",[2964,17391,17392,3490],{},[2977,17393,17394],{},"Builder для ImmutableArray",[3044,17396,17398],{"className":3046,"code":17397,"language":3049,"meta":3051,"style":3051},"var builder = ImmutableArray.CreateBuilder\u003Cint>();\nfor (int i = 0; i \u003C 1000; i++)\n{\n    builder.Add(i);  // Модифікує mutable builder\n}\nvar array = builder.ToImmutable();  // Одна immutable версія\n",[2968,17399,17400,17420,17448,17452,17468,17472],{"__ignoreMap":3051},[3055,17401,17402,17404,17406,17408,17410,17412,17414,17416,17418],{"class":3057,"line":3058},[3055,17403,3123],{"class":3122},[3055,17405,15159],{"class":3126},[3055,17407,3130],{"class":3069},[3055,17409,17084],{"class":3126},[3055,17411,3080],{"class":3069},[3055,17413,15168],{"class":3168},[3055,17415,3139],{"class":3069},[3055,17417,3142],{"class":3122},[3055,17419,3145],{"class":3069},[3055,17421,17422,17424,17426,17428,17430,17432,17434,17436,17438,17440,17442,17444,17446],{"class":3057,"line":3073},[3055,17423,15037],{"class":3061},[3055,17425,3204],{"class":3069},[3055,17427,3142],{"class":3122},[3055,17429,5444],{"class":3126},[3055,17431,3130],{"class":3069},[3055,17433,3176],{"class":3175},[3055,17435,3216],{"class":3069},[3055,17437,3186],{"class":3126},[3055,17439,3222],{"class":3069},[3055,17441,3225],{"class":3175},[3055,17443,3216],{"class":3069},[3055,17445,3186],{"class":3126},[3055,17447,3232],{"class":3069},[3055,17449,17450],{"class":3057,"line":3093},[3055,17451,3195],{"class":3069},[3055,17453,17454,17456,17458,17460,17462,17464,17466],{"class":3057,"line":3112},[3055,17455,15211],{"class":3126},[3055,17457,3080],{"class":3069},[3055,17459,3249],{"class":3168},[3055,17461,3172],{"class":3069},[3055,17463,3186],{"class":3126},[3055,17465,3266],{"class":3069},[3055,17467,15224],{"class":3156},[3055,17469,17470],{"class":3057,"line":3119},[3055,17471,3484],{"class":3069},[3055,17473,17474,17476,17479,17481,17483,17485,17487,17489],{"class":3057,"line":3148},[3055,17475,3123],{"class":3122},[3055,17477,17478],{"class":3126}," array",[3055,17480,3130],{"class":3069},[3055,17482,15240],{"class":3126},[3055,17484,3080],{"class":3069},[3055,17486,15245],{"class":3168},[3055,17488,5215],{"class":3069},[3055,17490,17491],{"class":3156},"// Одна immutable версія\n",[3032,17493,17495],{"id":17494},"практичний-приклад-thread-safe-configuration","Практичний Приклад: Thread-Safe Configuration",[3044,17497,17500],{"className":3046,"code":17498,"filename":17499,"language":3049,"meta":3050,"style":3051},"using System.Collections.Immutable;\n\npublic class AppConfiguration\n{\n    // Immutable словник — thread-safe для читання\n    private ImmutableDictionary\u003Cstring, string> _settings;\n\n    public AppConfiguration()\n    {\n        _settings = ImmutableDictionary\u003Cstring, string>.Empty;\n    }\n\n    // Читання — thread-safe без locks\n    public string? GetSetting(string key)\n    {\n        _settings.TryGetValue(key, out string? value);\n        return value;\n    }\n\n    // Запис — атомарна заміна через Interlocked\n    public void SetSetting(string key, string value)\n    {\n        ImmutableDictionary\u003Cstring, string> original, updated;\n        do\n        {\n            original = _settings;\n            updated = original.SetItem(key, value);\n        }\n        while (Interlocked.CompareExchange(ref _settings, updated, original) != original);\n    }\n\n    // Batch update\n    public void SetSettings(Dictionary\u003Cstring, string> updates)\n    {\n        ImmutableDictionary\u003Cstring, string> original, updated;\n        do\n        {\n            original = _settings;\n            updated = original.SetItems(updates);\n        }\n        while (Interlocked.CompareExchange(ref _settings, updated, original) != original);\n    }\n\n    public ImmutableDictionary\u003Cstring, string> GetAllSettings()\n    {\n        return _settings;  // Безпечно повертати — immutable!\n    }\n}\n\n// Використання:\nvar config = new AppConfiguration();\n\n// 100 потоків одночасно читають та пишуть\nParallel.For(0, 100, i =>\n{\n    // Запис\n    config.SetSetting($\"key-{i % 10}\", $\"value-{i}\");\n\n    // Читання (без locks!)\n    string? value = config.GetSetting($\"key-{i % 10}\");\n    Console.WriteLine($\"[Thread {i}] Read: {value}\");\n});\n\n// Отримати snapshot всіх налаштувань\nvar snapshot = config.GetAllSettings();\nConsole.WriteLine($\"Total settings: {snapshot.Count}\");\n","ThreadSafeConfig.cs",[2968,17501,17502,17518,17522,17531,17535,17540,17562,17566,17576,17580,17603,17607,17611,17616,17635,17639,17663,17671,17675,17679,17684,17707,17711,17735,17740,17744,17755,17778,17782,17819,17823,17827,17832,17859,17863,17885,17889,17893,17903,17921,17925,17957,17961,17965,17986,17990,18001,18005,18009,18013,18017,18032,18036,18041,18063,18067,18072,18113,18117,18122,18157,18188,18192,18196,18201,18218],{"__ignoreMap":3051},[3055,17503,17504,17506,17508,17510,17512,17514,17516],{"class":3057,"line":3058},[3055,17505,3062],{"class":3061},[3055,17507,3066],{"class":3065},[3055,17509,3080],{"class":3069},[3055,17511,3083],{"class":3065},[3055,17513,3080],{"class":3069},[3055,17515,13668],{"class":3065},[3055,17517,3070],{"class":3069},[3055,17519,17520],{"class":3057,"line":3073},[3055,17521,3116],{"emptyLinePlaceholder":3115},[3055,17523,17524,17526,17528],{"class":3057,"line":3093},[3055,17525,3367],{"class":3122},[3055,17527,6763],{"class":3122},[3055,17529,17530],{"class":3065}," AppConfiguration\n",[3055,17532,17533],{"class":3057,"line":3112},[3055,17534,3195],{"class":3069},[3055,17536,17537],{"class":3057,"line":3119},[3055,17538,17539],{"class":3156},"    // Immutable словник — thread-safe для читання\n",[3055,17541,17542,17544,17547,17549,17551,17553,17555,17557,17560],{"class":3057,"line":3148},[3055,17543,6799],{"class":3122},[3055,17545,17546],{"class":3065}," ImmutableDictionary",[3055,17548,3139],{"class":3069},[3055,17550,3580],{"class":3122},[3055,17552,2971],{"class":3069},[3055,17554,3580],{"class":3122},[3055,17556,6325],{"class":3069},[3055,17558,17559],{"class":3126},"_settings",[3055,17561,3070],{"class":3069},[3055,17563,17564],{"class":3057,"line":3153},[3055,17565,3116],{"emptyLinePlaceholder":3115},[3055,17567,17568,17570,17573],{"class":3057,"line":3160},[3055,17569,6878],{"class":3122},[3055,17571,17572],{"class":3168}," AppConfiguration",[3055,17574,17575],{"class":3069},"()\n",[3055,17577,17578],{"class":3057,"line":3192},[3055,17579,3238],{"class":3069},[3055,17581,17582,17585,17587,17589,17591,17593,17595,17597,17599,17601],{"class":3057,"line":3198},[3055,17583,17584],{"class":3126},"        _settings",[3055,17586,3130],{"class":3069},[3055,17588,13545],{"class":3126},[3055,17590,3139],{"class":3069},[3055,17592,3580],{"class":3122},[3055,17594,2971],{"class":3069},[3055,17596,3580],{"class":3122},[3055,17598,13556],{"class":3069},[3055,17600,13559],{"class":3126},[3055,17602,3070],{"class":3069},[3055,17604,17605],{"class":3057,"line":3235},[3055,17606,3275],{"class":3069},[3055,17608,17609],{"class":3057,"line":3241},[3055,17610,3116],{"emptyLinePlaceholder":3115},[3055,17612,17613],{"class":3057,"line":3272},[3055,17614,17615],{"class":3156},"    // Читання — thread-safe без locks\n",[3055,17617,17618,17620,17622,17624,17627,17629,17631,17633],{"class":3057,"line":3278},[3055,17619,6878],{"class":3122},[3055,17621,9806],{"class":3122},[3055,17623,6940],{"class":3069},[3055,17625,17626],{"class":3168},"GetSetting",[3055,17628,3172],{"class":3069},[3055,17630,3580],{"class":3122},[3055,17632,3673],{"class":3126},[3055,17634,3384],{"class":3069},[3055,17636,17637],{"class":3057,"line":3284},[3055,17638,3238],{"class":3069},[3055,17640,17641,17643,17645,17647,17649,17651,17653,17655,17657,17659,17661],{"class":3057,"line":3289},[3055,17642,17584],{"class":3126},[3055,17644,3080],{"class":3069},[3055,17646,4897],{"class":3168},[3055,17648,3172],{"class":3069},[3055,17650,3707],{"class":3126},[3055,17652,2971],{"class":3069},[3055,17654,4906],{"class":3122},[3055,17656,9806],{"class":3122},[3055,17658,6940],{"class":3069},[3055,17660,4937],{"class":3126},[3055,17662,3324],{"class":3069},[3055,17664,17665,17667,17669],{"class":3057,"line":3327},[3055,17666,5441],{"class":3061},[3055,17668,4912],{"class":3126},[3055,17670,3070],{"class":3069},[3055,17672,17673],{"class":3057,"line":3333},[3055,17674,3275],{"class":3069},[3055,17676,17677],{"class":3057,"line":3338},[3055,17678,3116],{"emptyLinePlaceholder":3115},[3055,17680,17681],{"class":3057,"line":3755},[3055,17682,17683],{"class":3156},"    // Запис — атомарна заміна через Interlocked\n",[3055,17685,17686,17688,17690,17693,17695,17697,17699,17701,17703,17705],{"class":3057,"line":3760},[3055,17687,6878],{"class":3122},[3055,17689,3370],{"class":3122},[3055,17691,17692],{"class":3168}," SetSetting",[3055,17694,3172],{"class":3069},[3055,17696,3580],{"class":3122},[3055,17698,3673],{"class":3126},[3055,17700,2971],{"class":3069},[3055,17702,3580],{"class":3122},[3055,17704,4912],{"class":3126},[3055,17706,3384],{"class":3069},[3055,17708,17709],{"class":3057,"line":3797},[3055,17710,3238],{"class":3069},[3055,17712,17713,17716,17718,17720,17722,17724,17726,17729,17731,17733],{"class":3057,"line":3826},[3055,17714,17715],{"class":3065},"        ImmutableDictionary",[3055,17717,3139],{"class":3069},[3055,17719,3580],{"class":3122},[3055,17721,2971],{"class":3069},[3055,17723,3580],{"class":3122},[3055,17725,6325],{"class":3069},[3055,17727,17728],{"class":3126},"original",[3055,17730,2971],{"class":3069},[3055,17732,6160],{"class":3126},[3055,17734,3070],{"class":3069},[3055,17736,17737],{"class":3057,"line":3831},[3055,17738,17739],{"class":3061},"        do\n",[3055,17741,17742],{"class":3057,"line":3836},[3055,17743,3665],{"class":3069},[3055,17745,17746,17749,17751,17753],{"class":3057,"line":3842},[3055,17747,17748],{"class":3126},"            original",[3055,17750,3130],{"class":3069},[3055,17752,17559],{"class":3126},[3055,17754,3070],{"class":3069},[3055,17756,17757,17760,17762,17764,17766,17768,17770,17772,17774,17776],{"class":3057,"line":3848},[3055,17758,17759],{"class":3126},"            updated",[3055,17761,3130],{"class":3069},[3055,17763,17728],{"class":3126},[3055,17765,3080],{"class":3069},[3055,17767,14078],{"class":3168},[3055,17769,3172],{"class":3069},[3055,17771,3707],{"class":3126},[3055,17773,2971],{"class":3069},[3055,17775,4937],{"class":3126},[3055,17777,3324],{"class":3069},[3055,17779,17780],{"class":3057,"line":3854},[3055,17781,3728],{"class":3069},[3055,17783,17784,17787,17789,17791,17793,17796,17798,17801,17804,17806,17808,17810,17812,17815,17817],{"class":3057,"line":4603},[3055,17785,17786],{"class":3061},"        while",[3055,17788,3204],{"class":3069},[3055,17790,2974],{"class":3126},[3055,17792,3080],{"class":3069},[3055,17794,17795],{"class":3168},"CompareExchange",[3055,17797,3172],{"class":3069},[3055,17799,17800],{"class":3122},"ref",[3055,17802,17803],{"class":3126}," _settings",[3055,17805,2971],{"class":3069},[3055,17807,6160],{"class":3126},[3055,17809,2971],{"class":3069},[3055,17811,17728],{"class":3126},[3055,17813,17814],{"class":3069},") != ",[3055,17816,17728],{"class":3126},[3055,17818,3324],{"class":3069},[3055,17820,17821],{"class":3057,"line":4609},[3055,17822,3275],{"class":3069},[3055,17824,17825],{"class":3057,"line":7082},[3055,17826,3116],{"emptyLinePlaceholder":3115},[3055,17828,17829],{"class":3057,"line":7095},[3055,17830,17831],{"class":3156},"    // Batch update\n",[3055,17833,17834,17836,17838,17841,17843,17845,17847,17849,17851,17853,17855,17857],{"class":3057,"line":7104},[3055,17835,6878],{"class":3122},[3055,17837,3370],{"class":3122},[3055,17839,17840],{"class":3168}," SetSettings",[3055,17842,3172],{"class":3069},[3055,17844,9027],{"class":3065},[3055,17846,3139],{"class":3069},[3055,17848,3580],{"class":3122},[3055,17850,2971],{"class":3069},[3055,17852,3580],{"class":3122},[3055,17854,6325],{"class":3069},[3055,17856,16001],{"class":3126},[3055,17858,3384],{"class":3069},[3055,17860,17861],{"class":3057,"line":7109},[3055,17862,3238],{"class":3069},[3055,17864,17865,17867,17869,17871,17873,17875,17877,17879,17881,17883],{"class":3057,"line":7114},[3055,17866,17715],{"class":3065},[3055,17868,3139],{"class":3069},[3055,17870,3580],{"class":3122},[3055,17872,2971],{"class":3069},[3055,17874,3580],{"class":3122},[3055,17876,6325],{"class":3069},[3055,17878,17728],{"class":3126},[3055,17880,2971],{"class":3069},[3055,17882,6160],{"class":3126},[3055,17884,3070],{"class":3069},[3055,17886,17887],{"class":3057,"line":7152},[3055,17888,17739],{"class":3061},[3055,17890,17891],{"class":3057,"line":7157},[3055,17892,3665],{"class":3069},[3055,17894,17895,17897,17899,17901],{"class":3057,"line":7187},[3055,17896,17748],{"class":3126},[3055,17898,3130],{"class":3069},[3055,17900,17559],{"class":3126},[3055,17902,3070],{"class":3069},[3055,17904,17905,17907,17909,17911,17913,17915,17917,17919],{"class":3057,"line":7211},[3055,17906,17759],{"class":3126},[3055,17908,3130],{"class":3069},[3055,17910,17728],{"class":3126},[3055,17912,3080],{"class":3069},[3055,17914,15996],{"class":3168},[3055,17916,3172],{"class":3069},[3055,17918,16001],{"class":3126},[3055,17920,3324],{"class":3069},[3055,17922,17923],{"class":3057,"line":7216},[3055,17924,3728],{"class":3069},[3055,17926,17927,17929,17931,17933,17935,17937,17939,17941,17943,17945,17947,17949,17951,17953,17955],{"class":3057,"line":7235},[3055,17928,17786],{"class":3061},[3055,17930,3204],{"class":3069},[3055,17932,2974],{"class":3126},[3055,17934,3080],{"class":3069},[3055,17936,17795],{"class":3168},[3055,17938,3172],{"class":3069},[3055,17940,17800],{"class":3122},[3055,17942,17803],{"class":3126},[3055,17944,2971],{"class":3069},[3055,17946,6160],{"class":3126},[3055,17948,2971],{"class":3069},[3055,17950,17728],{"class":3126},[3055,17952,17814],{"class":3069},[3055,17954,17728],{"class":3126},[3055,17956,3324],{"class":3069},[3055,17958,17959],{"class":3057,"line":7240},[3055,17960,3275],{"class":3069},[3055,17962,17963],{"class":3057,"line":7245},[3055,17964,3116],{"emptyLinePlaceholder":3115},[3055,17966,17967,17969,17971,17973,17975,17977,17979,17981,17984],{"class":3057,"line":7293},[3055,17968,6878],{"class":3122},[3055,17970,17546],{"class":3065},[3055,17972,3139],{"class":3069},[3055,17974,3580],{"class":3122},[3055,17976,2971],{"class":3069},[3055,17978,3580],{"class":3122},[3055,17980,6325],{"class":3069},[3055,17982,17983],{"class":3168},"GetAllSettings",[3055,17985,17575],{"class":3069},[3055,17987,17988],{"class":3057,"line":7298},[3055,17989,3238],{"class":3069},[3055,17991,17992,17994,17996,17998],{"class":3057,"line":7323},[3055,17993,5441],{"class":3061},[3055,17995,17803],{"class":3126},[3055,17997,3465],{"class":3069},[3055,17999,18000],{"class":3156},"// Безпечно повертати — immutable!\n",[3055,18002,18003],{"class":3057,"line":7328},[3055,18004,3275],{"class":3069},[3055,18006,18007],{"class":3057,"line":7353},[3055,18008,3484],{"class":3069},[3055,18010,18011],{"class":3057,"line":7358},[3055,18012,3116],{"emptyLinePlaceholder":3115},[3055,18014,18015],{"class":3057,"line":7376},[3055,18016,7584],{"class":3156},[3055,18018,18019,18021,18024,18026,18028,18030],{"class":3057,"line":7396},[3055,18020,3123],{"class":3122},[3055,18022,18023],{"class":3126}," config",[3055,18025,3130],{"class":3069},[3055,18027,3133],{"class":3122},[3055,18029,17572],{"class":3065},[3055,18031,4071],{"class":3069},[3055,18033,18034],{"class":3057,"line":7402},[3055,18035,3116],{"emptyLinePlaceholder":3115},[3055,18037,18038],{"class":3057,"line":7407},[3055,18039,18040],{"class":3156},"// 100 потоків одночасно читають та пишуть\n",[3055,18042,18043,18045,18047,18049,18051,18053,18055,18057,18059,18061],{"class":3057,"line":7413},[3055,18044,3163],{"class":3126},[3055,18046,3080],{"class":3069},[3055,18048,3169],{"class":3168},[3055,18050,3172],{"class":3069},[3055,18052,3176],{"class":3175},[3055,18054,2971],{"class":3069},[3055,18056,4693],{"class":3175},[3055,18058,2971],{"class":3069},[3055,18060,3186],{"class":3126},[3055,18062,3189],{"class":3069},[3055,18064,18065],{"class":3057,"line":7437},[3055,18066,3195],{"class":3069},[3055,18068,18069],{"class":3057,"line":7442},[3055,18070,18071],{"class":3156},"    // Запис\n",[3055,18073,18074,18077,18079,18082,18084,18086,18088,18090,18092,18094,18096,18098,18100,18103,18105,18107,18109,18111],{"class":3057,"line":7448},[3055,18075,18076],{"class":3126},"    config",[3055,18078,3080],{"class":3069},[3055,18080,18081],{"class":3168},"SetSetting",[3055,18083,3172],{"class":3069},[3055,18085,3678],{"class":3302},[3055,18087,3307],{"class":3306},[3055,18089,3186],{"class":3126},[3055,18091,5895],{"class":3069},[3055,18093,5898],{"class":3175},[3055,18095,3318],{"class":3306},[3055,18097,3321],{"class":3302},[3055,18099,2971],{"class":3069},[3055,18101,18102],{"class":3302},"$\"value-",[3055,18104,3307],{"class":3306},[3055,18106,3186],{"class":3126},[3055,18108,3318],{"class":3306},[3055,18110,3321],{"class":3302},[3055,18112,3324],{"class":3069},[3055,18114,18115],{"class":3057,"line":7469},[3055,18116,3116],{"emptyLinePlaceholder":3115},[3055,18118,18119],{"class":3057,"line":7490},[3055,18120,18121],{"class":3156},"    // Читання (без locks!)\n",[3055,18123,18124,18126,18128,18130,18132,18135,18137,18139,18141,18143,18145,18147,18149,18151,18153,18155],{"class":3057,"line":7495},[3055,18125,5881],{"class":3122},[3055,18127,6940],{"class":3069},[3055,18129,4937],{"class":3126},[3055,18131,3130],{"class":3069},[3055,18133,18134],{"class":3126},"config",[3055,18136,3080],{"class":3069},[3055,18138,17626],{"class":3168},[3055,18140,3172],{"class":3069},[3055,18142,3678],{"class":3302},[3055,18144,3307],{"class":3306},[3055,18146,3186],{"class":3126},[3055,18148,5895],{"class":3069},[3055,18150,5898],{"class":3175},[3055,18152,3318],{"class":3306},[3055,18154,3321],{"class":3302},[3055,18156,3324],{"class":3069},[3055,18158,18159,18161,18163,18165,18167,18169,18171,18173,18175,18178,18180,18182,18184,18186],{"class":3057,"line":7500},[3055,18160,3763],{"class":3126},[3055,18162,3080],{"class":3069},[3055,18164,3297],{"class":3168},[3055,18166,3172],{"class":3069},[3055,18168,7740],{"class":3302},[3055,18170,3307],{"class":3306},[3055,18172,3186],{"class":3126},[3055,18174,3318],{"class":3306},[3055,18176,18177],{"class":3302},"] Read: ",[3055,18179,3307],{"class":3306},[3055,18181,4937],{"class":3126},[3055,18183,3318],{"class":3306},[3055,18185,3321],{"class":3302},[3055,18187,3324],{"class":3069},[3055,18189,18190],{"class":3057,"line":7513},[3055,18191,3281],{"class":3069},[3055,18193,18194],{"class":3057,"line":7518},[3055,18195,3116],{"emptyLinePlaceholder":3115},[3055,18197,18198],{"class":3057,"line":7523},[3055,18199,18200],{"class":3156},"// Отримати snapshot всіх налаштувань\n",[3055,18202,18203,18205,18208,18210,18212,18214,18216],{"class":3057,"line":7545},[3055,18204,3123],{"class":3122},[3055,18206,18207],{"class":3126}," snapshot",[3055,18209,3130],{"class":3069},[3055,18211,18134],{"class":3126},[3055,18213,3080],{"class":3069},[3055,18215,17983],{"class":3168},[3055,18217,4071],{"class":3069},[3055,18219,18220,18222,18224,18226,18228,18231,18233,18235,18237,18239,18241,18243],{"class":3057,"line":7550},[3055,18221,3292],{"class":3126},[3055,18223,3080],{"class":3069},[3055,18225,3297],{"class":3168},[3055,18227,3172],{"class":3069},[3055,18229,18230],{"class":3302},"$\"Total settings: ",[3055,18232,3307],{"class":3306},[3055,18234,9451],{"class":3126},[3055,18236,3080],{"class":3306},[3055,18238,3315],{"class":3126},[3055,18240,3318],{"class":3306},[3055,18242,3321],{"class":3302},[3055,18244,3324],{"class":3069},[2964,18246,18247],{},[2977,18248,18249],{},"Чому це працює без locks для читання?",[3009,18251,18252,18260,18267,18273],{},[3012,18253,18254,9448,18256,18259],{},[2968,18255,17559],{},[2977,18257,18258],{},"reference"," на immutable колекцію",[3012,18261,18262,18263,18266],{},"Читання reference — ",[2977,18264,18265],{},"атомарна"," операція на всіх платформах",[3012,18268,18269,18270,18272],{},"Навіть якщо інший потік замінює ",[2968,18271,17559],{},", ми отримаємо або стару або нову версію (обидві валідні)",[3012,18274,18275],{},"Immutable колекція не може бути \"частково змінена\" — вона або стара або нова",[3032,18277,18279],{"id":18278},"concurrent-vs-immutable-коли-що-використовувати","Concurrent vs Immutable: Коли Що Використовувати",[18281,18282,18283,18343],"card-group",{},[18284,18285,18287,18292,18311,18316,18327,18332],"card",{"icon":18286,"title":4274},"i-lucide-lock",[2964,18288,18289],{},[2977,18290,18291],{},"Переваги:",[3009,18293,18294,18297,18300,18303],{},[3012,18295,18296],{},"Модифікація \"на місці\" (in-place)",[3012,18298,18299],{},"O(1) операції (в середньому)",[3012,18301,18302],{},"Менше GC pressure (не створює нові об'єкти)",[3012,18304,18305,18306,2971,18308,18310],{},"Вбудовані atomic операції (",[2968,18307,5066],{},[2968,18309,5545],{},")",[2964,18312,18313],{},[2977,18314,18315],{},"Недоліки:",[3009,18317,18318,18321,18324],{},[3012,18319,18320],{},"Lock contention при високій конкуренції",[3012,18322,18323],{},"Складніший API",[3012,18325,18326],{},"Не можна безпечно ітерувати під час модифікації",[2964,18328,18329],{},[2977,18330,18331],{},"Use cases:",[3009,18333,18334,18337,18340],{},[3012,18335,18336],{},"Часті модифікації з різних потоків",[3012,18338,18339],{},"Потрібні atomic операції",[3012,18341,18342],{},"Великі колекції (мільйони елементів)",[18284,18344,18346,18350,18364,18368,18379,18383],{"icon":18345,"title":13545},"i-lucide-shield",[2964,18347,18348],{},[2977,18349,18291],{},[3009,18351,18352,18355,18358,18361],{},[3012,18353,18354],{},"Абсолютно thread-safe для читання (без locks!)",[3012,18356,18357],{},"Можна безпечно передавати між потоками",[3012,18359,18360],{},"Snapshot semantics (версіонування стану)",[3012,18362,18363],{},"Functional programming style",[2964,18365,18366],{},[2977,18367,18315],{},[3009,18369,18370,18373,18376],{},[3012,18371,18372],{},"O(log n) операції (повільніше)",[3012,18374,18375],{},"Більше GC pressure (створює нові об'єкти)",[3012,18377,18378],{},"Потребує CAS loop для модифікацій",[2964,18380,18381],{},[2977,18382,18331],{},[3009,18384,18385,18388,18391,18394],{},[3012,18386,18387],{},"Рідкісні модифікації, часті читання",[3012,18389,18390],{},"Потрібні snapshots стану",[3012,18392,18393],{},"Functional/immutable architecture",[3012,18395,18396],{},"Конфігурація, кеші",[3032,18398,18400],{"id":18399},"порівняльна-таблиця","Порівняльна Таблиця",[18402,18403,18404,18418],"table",{},[18405,18406,18407],"thead",{},[18408,18409,18410,18414,18416],"tr",{},[18411,18412,18413],"th",{},"Критерій",[18411,18415,6738],{},[18411,18417,13668],{},[18419,18420,18421,18435,18448,18461,18474,18487],"tbody",{},[18408,18422,18423,18429,18432],{},[18424,18425,18426],"td",{},[2977,18427,18428],{},"Читання",[18424,18430,18431],{},"O(1), lock-free",[18424,18433,18434],{},"O(log n), абсолютно безпечне",[18408,18436,18437,18442,18445],{},[18424,18438,18439],{},[2977,18440,18441],{},"Запис",[18424,18443,18444],{},"O(1), striped locking",[18424,18446,18447],{},"O(log n), CAS loop",[18408,18449,18450,18455,18458],{},[18424,18451,18452],{},[2977,18453,18454],{},"GC Pressure",[18424,18456,18457],{},"Низький",[18424,18459,18460],{},"Середній (structural sharing)",[18408,18462,18463,18468,18471],{},[18424,18464,18465],{},[2977,18466,18467],{},"Ітерація під час модифікації",[18424,18469,18470],{},"Snapshot (може бути застарілим)",[18424,18472,18473],{},"Завжди консистентний snapshot",[18408,18475,18476,18481,18484],{},[18424,18477,18478],{},[2977,18479,18480],{},"API складність",[18424,18482,18483],{},"Середня",[18424,18485,18486],{},"Проста (functional style)",[18408,18488,18489,18494,18497],{},[18424,18490,18491],{},[2977,18492,18493],{},"Best for",[18424,18495,18496],{},"High-throughput mutations",[18424,18498,18499],{},"Read-heavy, snapshots",[3025,18501],{},[2959,18503,18505],{"id":18504},"benchmarks-порівняння-продуктивності","Benchmarks: Порівняння Продуктивності",[2964,18507,18508],{},"Давайте порівняємо продуктивність різних підходів до thread-safe колекцій на реальних сценаріях.",[3032,18510,18512],{"id":18511},"benchmark-1-concurrent-writes-10000-операцій-8-потоків","Benchmark 1: Concurrent Writes (10,000 операцій, 8 потоків)",[2964,18514,18515,18517],{},[2977,18516,7870],{},": 8 потоків одночасно додають по 10,000 елементів у словник.",[3044,18519,18521],{"className":3046,"code":18520,"language":3049,"meta":3051,"style":3051},"// Dictionary + lock\nvar dict = new Dictionary\u003Cstring, int>();\nvar lockObj = new object();\nParallel.For(0, 80000, i =>\n{\n    lock (lockObj)\n    {\n        dict[$\"key-{i}\"] = i;\n    }\n});\n\n// ConcurrentDictionary\nvar concurrent = new ConcurrentDictionary\u003Cstring, int>();\nParallel.For(0, 80000, i =>\n{\n    concurrent[$\"key-{i}\"] = i;\n});\n\n// ImmutableDictionary\nvar immutable = ImmutableDictionary\u003Cstring, int>.Empty;\nParallel.For(0, 80000, i =>\n{\n    ImmutableDictionary\u003Cstring, int> original, updated;\n    do\n    {\n        original = immutable;\n        updated = original.SetItem($\"key-{i}\", i);\n    }\n    while (Interlocked.CompareExchange(ref immutable, updated, original) != original);\n});\n",[2968,18522,18523,18528,18550,18564,18587,18591,18602,18606,18629,18633,18637,18641,18646,18668,18690,18694,18717,18721,18725,18730,18754,18776,18780,18803,18808,18812,18823,18854,18858,18890],{"__ignoreMap":3051},[3055,18524,18525],{"class":3057,"line":3058},[3055,18526,18527],{"class":3156},"// Dictionary + lock\n",[3055,18529,18530,18532,18534,18536,18538,18540,18542,18544,18546,18548],{"class":3057,"line":3073},[3055,18531,3123],{"class":3122},[3055,18533,3568],{"class":3126},[3055,18535,3130],{"class":3069},[3055,18537,3133],{"class":3122},[3055,18539,3575],{"class":3065},[3055,18541,3139],{"class":3069},[3055,18543,3580],{"class":3122},[3055,18545,2971],{"class":3069},[3055,18547,3142],{"class":3122},[3055,18549,3145],{"class":3069},[3055,18551,18552,18554,18556,18558,18560,18562],{"class":3057,"line":3093},[3055,18553,3123],{"class":3122},[3055,18555,4061],{"class":3126},[3055,18557,3130],{"class":3069},[3055,18559,3133],{"class":3122},[3055,18561,4068],{"class":3122},[3055,18563,4071],{"class":3069},[3055,18565,18566,18568,18570,18572,18574,18576,18578,18581,18583,18585],{"class":3057,"line":3112},[3055,18567,3163],{"class":3126},[3055,18569,3080],{"class":3069},[3055,18571,3169],{"class":3168},[3055,18573,3172],{"class":3069},[3055,18575,3176],{"class":3175},[3055,18577,2971],{"class":3069},[3055,18579,18580],{"class":3175},"80000",[3055,18582,2971],{"class":3069},[3055,18584,3186],{"class":3126},[3055,18586,3189],{"class":3069},[3055,18588,18589],{"class":3057,"line":3119},[3055,18590,3195],{"class":3069},[3055,18592,18593,18596,18598,18600],{"class":3057,"line":3148},[3055,18594,18595],{"class":3061},"    lock",[3055,18597,3204],{"class":3069},[3055,18599,4181],{"class":3126},[3055,18601,3384],{"class":3069},[3055,18603,18604],{"class":3057,"line":3153},[3055,18605,3238],{"class":3069},[3055,18607,18608,18611,18613,18615,18617,18619,18621,18623,18625,18627],{"class":3057,"line":3160},[3055,18609,18610],{"class":3126},"        dict",[3055,18612,3454],{"class":3069},[3055,18614,3678],{"class":3302},[3055,18616,3307],{"class":3306},[3055,18618,3186],{"class":3126},[3055,18620,3318],{"class":3306},[3055,18622,3321],{"class":3302},[3055,18624,3459],{"class":3069},[3055,18626,3186],{"class":3126},[3055,18628,3070],{"class":3069},[3055,18630,18631],{"class":3057,"line":3192},[3055,18632,3275],{"class":3069},[3055,18634,18635],{"class":3057,"line":3198},[3055,18636,3281],{"class":3069},[3055,18638,18639],{"class":3057,"line":3235},[3055,18640,3116],{"emptyLinePlaceholder":3115},[3055,18642,18643],{"class":3057,"line":3241},[3055,18644,18645],{"class":3156},"// ConcurrentDictionary\n",[3055,18647,18648,18650,18652,18654,18656,18658,18660,18662,18664,18666],{"class":3057,"line":3272},[3055,18649,3123],{"class":3122},[3055,18651,13489],{"class":3126},[3055,18653,3130],{"class":3069},[3055,18655,3133],{"class":3122},[3055,18657,4646],{"class":3065},[3055,18659,3139],{"class":3069},[3055,18661,3580],{"class":3122},[3055,18663,2971],{"class":3069},[3055,18665,3142],{"class":3122},[3055,18667,3145],{"class":3069},[3055,18669,18670,18672,18674,18676,18678,18680,18682,18684,18686,18688],{"class":3057,"line":3278},[3055,18671,3163],{"class":3126},[3055,18673,3080],{"class":3069},[3055,18675,3169],{"class":3168},[3055,18677,3172],{"class":3069},[3055,18679,3176],{"class":3175},[3055,18681,2971],{"class":3069},[3055,18683,18580],{"class":3175},[3055,18685,2971],{"class":3069},[3055,18687,3186],{"class":3126},[3055,18689,3189],{"class":3069},[3055,18691,18692],{"class":3057,"line":3284},[3055,18693,3195],{"class":3069},[3055,18695,18696,18699,18701,18703,18705,18707,18709,18711,18713,18715],{"class":3057,"line":3289},[3055,18697,18698],{"class":3126},"    concurrent",[3055,18700,3454],{"class":3069},[3055,18702,3678],{"class":3302},[3055,18704,3307],{"class":3306},[3055,18706,3186],{"class":3126},[3055,18708,3318],{"class":3306},[3055,18710,3321],{"class":3302},[3055,18712,3459],{"class":3069},[3055,18714,3186],{"class":3126},[3055,18716,3070],{"class":3069},[3055,18718,18719],{"class":3057,"line":3327},[3055,18720,3281],{"class":3069},[3055,18722,18723],{"class":3057,"line":3333},[3055,18724,3116],{"emptyLinePlaceholder":3115},[3055,18726,18727],{"class":3057,"line":3338},[3055,18728,18729],{"class":3156},"// ImmutableDictionary\n",[3055,18731,18732,18734,18736,18738,18740,18742,18744,18746,18748,18750,18752],{"class":3057,"line":3755},[3055,18733,3123],{"class":3122},[3055,18735,13540],{"class":3126},[3055,18737,3130],{"class":3069},[3055,18739,13545],{"class":3126},[3055,18741,3139],{"class":3069},[3055,18743,3580],{"class":3122},[3055,18745,2971],{"class":3069},[3055,18747,3142],{"class":3122},[3055,18749,13556],{"class":3069},[3055,18751,13559],{"class":3126},[3055,18753,3070],{"class":3069},[3055,18755,18756,18758,18760,18762,18764,18766,18768,18770,18772,18774],{"class":3057,"line":3760},[3055,18757,3163],{"class":3126},[3055,18759,3080],{"class":3069},[3055,18761,3169],{"class":3168},[3055,18763,3172],{"class":3069},[3055,18765,3176],{"class":3175},[3055,18767,2971],{"class":3069},[3055,18769,18580],{"class":3175},[3055,18771,2971],{"class":3069},[3055,18773,3186],{"class":3126},[3055,18775,3189],{"class":3069},[3055,18777,18778],{"class":3057,"line":3797},[3055,18779,3195],{"class":3069},[3055,18781,18782,18785,18787,18789,18791,18793,18795,18797,18799,18801],{"class":3057,"line":3826},[3055,18783,18784],{"class":3065},"    ImmutableDictionary",[3055,18786,3139],{"class":3069},[3055,18788,3580],{"class":3122},[3055,18790,2971],{"class":3069},[3055,18792,3142],{"class":3122},[3055,18794,6325],{"class":3069},[3055,18796,17728],{"class":3126},[3055,18798,2971],{"class":3069},[3055,18800,6160],{"class":3126},[3055,18802,3070],{"class":3069},[3055,18804,18805],{"class":3057,"line":3831},[3055,18806,18807],{"class":3061},"    do\n",[3055,18809,18810],{"class":3057,"line":3836},[3055,18811,3238],{"class":3069},[3055,18813,18814,18817,18819,18821],{"class":3057,"line":3842},[3055,18815,18816],{"class":3126},"        original",[3055,18818,3130],{"class":3069},[3055,18820,13573],{"class":3126},[3055,18822,3070],{"class":3069},[3055,18824,18825,18828,18830,18832,18834,18836,18838,18840,18842,18844,18846,18848,18850,18852],{"class":3057,"line":3848},[3055,18826,18827],{"class":3126},"        updated",[3055,18829,3130],{"class":3069},[3055,18831,17728],{"class":3126},[3055,18833,3080],{"class":3069},[3055,18835,14078],{"class":3168},[3055,18837,3172],{"class":3069},[3055,18839,3678],{"class":3302},[3055,18841,3307],{"class":3306},[3055,18843,3186],{"class":3126},[3055,18845,3318],{"class":3306},[3055,18847,3321],{"class":3302},[3055,18849,2971],{"class":3069},[3055,18851,3186],{"class":3126},[3055,18853,3324],{"class":3069},[3055,18855,18856],{"class":3057,"line":3854},[3055,18857,3275],{"class":3069},[3055,18859,18860,18862,18864,18866,18868,18870,18872,18874,18876,18878,18880,18882,18884,18886,18888],{"class":3057,"line":4603},[3055,18861,6353],{"class":3061},[3055,18863,3204],{"class":3069},[3055,18865,2974],{"class":3126},[3055,18867,3080],{"class":3069},[3055,18869,17795],{"class":3168},[3055,18871,3172],{"class":3069},[3055,18873,17800],{"class":3122},[3055,18875,13540],{"class":3126},[3055,18877,2971],{"class":3069},[3055,18879,6160],{"class":3126},[3055,18881,2971],{"class":3069},[3055,18883,17728],{"class":3126},[3055,18885,17814],{"class":3069},[3055,18887,17728],{"class":3126},[3055,18889,3324],{"class":3069},[3055,18891,18892],{"class":3057,"line":4609},[3055,18893,3281],{"class":3069},[2964,18895,18896,3490],{},[2977,18897,18898],{},"Результати",[3044,18900,18903],{"className":18901,"code":18902,"language":3496},[3494],"┌─────────────────────────┬──────────┬────────────┐\n│ Підхід                  │ Час (ms) │ Відносно   │\n├─────────────────────────┼──────────┼────────────┤\n│ Dictionary + lock       │ 3,500    │ 1.0x       │\n│ ConcurrentDictionary    │ 1,200    │ 2.9x швидше│\n│ ImmutableDictionary     │ 8,900    │ 0.4x       │\n└─────────────────────────┴──────────┴────────────┘\n",[2968,18904,18902],{"__ignoreMap":3051},[2964,18906,18907,18910,18911,18913],{},[2977,18908,18909],{},"Висновок",": Для частих конкурентних записів ",[2968,18912,4274],{}," найкращий вибір.",[3032,18915,18917],{"id":18916},"benchmark-2-read-heavy-workload-90-читання-10-запис","Benchmark 2: Read-Heavy Workload (90% читання, 10% запис)",[2964,18919,18920,18922],{},[2977,18921,7870],{},": 8 потоків виконують 90% операцій читання та 10% запису.",[3044,18924,18927],{"className":18925,"code":18926,"language":3496},[3494],"┌─────────────────────────┬──────────┬────────────┐\n│ Підхід                  │ Час (ms) │ Відносно   │\n├─────────────────────────┼──────────┼────────────┤\n│ Dictionary + lock       │ 2,100    │ 1.0x       │\n│ ConcurrentDictionary    │ 850      │ 2.5x швидше│\n│ ImmutableDictionary     │ 650      │ 3.2x швидше│\n└─────────────────────────┴──────────┴────────────┘\n",[2968,18928,18926],{"__ignoreMap":3051},[2964,18930,18931,18933,18934,18936],{},[2977,18932,18909],{},": Для read-heavy сценаріїв ",[2968,18935,13545],{}," найшвидший (читання без locks!).",[3032,18938,18940],{"id":18939},"benchmark-3-producer-consumer-1-producer-1-consumer","Benchmark 3: Producer-Consumer (1 producer, 1 consumer)",[2964,18942,18943,18945],{},[2977,18944,7870],{},": Один потік додає 100,000 елементів, інший забирає.",[3044,18947,18950],{"className":18948,"code":18949,"language":3496},[3494],"┌─────────────────────────┬──────────┬────────────┐\n│ Підхід                  │ Час (ms) │ Відносно   │\n├─────────────────────────┼──────────┼────────────┤\n│ Queue + lock            │ 450      │ 1.0x       │\n│ ConcurrentQueue         │ 180      │ 2.5x швидше│\n│ BlockingCollection      │ 220      │ 2.0x швидше│\n└─────────────────────────┴──────────┴────────────┘\n",[2968,18951,18949],{"__ignoreMap":3051},[2964,18953,18954,5292,18956,18958,18959,18961],{},[2977,18955,18909],{},[2968,18957,9058],{}," найшвидша для простого producer-consumer. ",[2968,18960,11143],{}," трохи повільніша, але надає bounded capacity та блокуючу семантику.",[3032,18963,18965],{"id":18964},"benchmark-4-parallelforeach-з-агрегацією-результатів","Benchmark 4: Parallel.ForEach з агрегацією результатів",[2964,18967,18968,18970],{},[2977,18969,7870],{},": 8 потоків обробляють 10,000 елементів кожен та додають результати.",[3044,18972,18975],{"className":18973,"code":18974,"language":3496},[3494],"┌─────────────────────────┬──────────┬────────────┐\n│ Підхід                  │ Час (ms) │ Відносно   │\n├─────────────────────────┼──────────┼────────────┤\n│ List + lock             │ 520      │ 1.0x       │\n│ ConcurrentQueue         │ 280      │ 1.9x швидше│\n│ ConcurrentBag           │ 190      │ 2.7x швидше│\n└─────────────────────────┴──────────┴────────────┘\n",[2968,18976,18974],{"__ignoreMap":3051},[2964,18978,18979,5292,18981,18983],{},[2977,18980,18909],{},[2968,18982,10455],{}," найкращий для Parallel.ForEach завдяки thread-local optimization.",[3032,18985,18987],{"id":18986},"benchmark-5-memory-overhead","Benchmark 5: Memory Overhead",[2964,18989,18990,18992],{},[2977,18991,7870],{},": Пам'ять для зберігання 100,000 елементів.",[3044,18994,18997],{"className":18995,"code":18996,"language":3496},[3494],"┌─────────────────────────┬──────────┬────────────┐\n│ Колекція                │ Пам'ять  │ Відносно   │\n├─────────────────────────┼──────────┼────────────┤\n│ Dictionary\u003CK,V>         │ 8.2 MB   │ 1.0x       │\n│ ConcurrentDictionary    │ 12.5 MB  │ 1.5x більше│\n│ ImmutableDictionary     │ 15.8 MB  │ 1.9x більше│\n│ List\u003CT>                 │ 4.1 MB   │ 1.0x       │\n│ ImmutableList\u003CT>        │ 8.9 MB   │ 2.2x більше│\n│ ImmutableArray\u003CT>       │ 4.1 MB   │ 1.0x       │\n└─────────────────────────┴──────────┴────────────┘\n",[2968,18998,18996],{"__ignoreMap":3051},[2964,19000,19001,19003],{},[2977,19002,18909],{},": Concurrent та Immutable колекції використовують більше пам'яті через додаткові структури (locks, tree nodes).",[3032,19005,19007],{"id":19006},"ключові-висновки-з-benchmarks","Ключові Висновки з Benchmarks",[19009,19010,19011,19016],"tip",{},[2964,19012,19013,3490],{},[2977,19014,19015],{},"Правило вибору колекції",[3877,19017,19018,19028,19037,19048,19055,19062],{},[3012,19019,19020,19023,19024,2971,19026],{},[2977,19021,19022],{},"Часті конкурентні записи"," → ",[2968,19025,4274],{},[2968,19027,9058],{},[3012,19029,19030,19023,19033,2971,19035],{},[2977,19031,19032],{},"Read-heavy (90%+ читання)",[2968,19034,13545],{},[2968,19036,13645],{},[3012,19038,19039,19023,19042,19044,19045,19047],{},[2977,19040,19041],{},"Producer-Consumer",[2968,19043,9058],{}," (unbounded) або ",[2968,19046,11143],{}," (bounded)",[3012,19049,19050,19023,19053],{},[2977,19051,19052],{},"Parallel.ForEach з агрегацією",[2968,19054,10455],{},[3012,19056,19057,19023,19060],{},[2977,19058,19059],{},"Рідкісні зміни + швидкий доступ",[2968,19061,17084],{},[3012,19063,19064,19067],{},[2977,19065,19066],{},"Snapshots та версіонування"," → Immutable колекції",[3025,19069],{},[2959,19071,19073],{"id":19072},"зведена-таблиця-всі-concurrent-та-immutable-collections","Зведена Таблиця: Всі Concurrent та Immutable Collections",[2964,19075,19076],{},"Ось повний огляд всіх thread-safe колекцій у .NET з їх характеристиками:",[18402,19078,19079,19100],{},[18405,19080,19081],{},[18408,19082,19083,19086,19089,19092,19094,19097],{},[18411,19084,19085],{},"Колекція",[18411,19087,19088],{},"Тип",[18411,19090,19091],{},"Порядок",[18411,19093,10046],{},[18411,19095,19096],{},"Складність",[18411,19098,19099],{},"Use Case",[18419,19101,19102,19119,19147,19171,19194,19217,19240,19256,19280,19303,19327,19351,19373,19395],{},[18408,19103,19104,19109,19111,19113,19115,19117],{},[18424,19105,19106],{},[2977,19107,19108],{},"Concurrent Collections",[18424,19110],{},[18424,19112],{},[18424,19114],{},[18424,19116],{},[18424,19118],{},[18408,19120,19121,19126,19128,19131,19141,19144],{},[18424,19122,19123],{},[2968,19124,19125],{},"ConcurrentDictionary\u003CK,V>",[18424,19127,9027],{},[18424,19129,19130],{},"Немає",[18424,19132,19133,2971,19135,2971,19137,2971,19139],{},[2968,19134,4683],{},[2968,19136,6599],{},[2968,19138,5066],{},[2968,19140,5545],{},[18424,19142,19143],{},"O(1) avg",[18424,19145,19146],{},"Часті конкурентні read/write",[18408,19148,19149,19153,19156,19159,19165,19168],{},[18424,19150,19151],{},[2968,19152,9070],{},[18424,19154,19155],{},"Queue",[18424,19157,19158],{},"FIFO",[18424,19160,19161,2971,19163],{},[2968,19162,9095],{},[2968,19164,9105],{},[18424,19166,19167],{},"O(1)",[18424,19169,19170],{},"Producer-consumer, unbounded",[18408,19172,19173,19177,19180,19183,19189,19191],{},[18424,19174,19175],{},[2968,19176,10028],{},[18424,19178,19179],{},"Stack",[18424,19181,19182],{},"LIFO",[18424,19184,19185,2971,19187],{},[2968,19186,10053],{},[2968,19188,10059],{},[18424,19190,19167],{},[18424,19192,19193],{},"LIFO сценарії",[18408,19195,19196,19200,19203,19205,19211,19214],{},[18424,19197,19198],{},[2968,19199,10467],{},[18424,19201,19202],{},"Bag",[18424,19204,19130],{},[18424,19206,19207,2971,19209],{},[2968,19208,3249],{},[2968,19210,10699],{},[18424,19212,19213],{},"O(1) local",[18424,19215,19216],{},"Parallel.ForEach агрегація",[18408,19218,19219,19223,19225,19227,19235,19237],{},[18424,19220,19221],{},[2968,19222,11866],{},[18424,19224,19155],{},[18424,19226,19158],{},[18424,19228,19229,2971,19231,2971,19233],{},[2968,19230,3249],{},[2968,19232,8354],{},[2968,19234,11899],{},[18424,19236,19167],{},[18424,19238,19239],{},"Bounded producer-consumer",[18408,19241,19242,19246,19248,19250,19252,19254],{},[18424,19243,19244],{},[2977,19245,13442],{},[18424,19247],{},[18424,19249],{},[18424,19251],{},[18424,19253],{},[18424,19255],{},[18408,19257,19258,19262,19265,19268,19276,19278],{},[18424,19259,19260],{},[2968,19261,14202],{},[18424,19263,19264],{},"List",[18424,19266,19267],{},"Insertion",[18424,19269,19270,2971,19272,2971,19274],{},[2968,19271,3249],{},[2968,19273,13932],{},[2968,19275,14078],{},[18424,19277,14916],{},[18424,19279,18499],{},[18408,19281,19282,19286,19288,19290,19298,19300],{},[18424,19283,19284],{},[2968,19285,14859],{},[18424,19287,9027],{},[18424,19289,19130],{},[18424,19291,19292,2971,19294,2971,19296],{},[2968,19293,3249],{},[2968,19295,13932],{},[2968,19297,14078],{},[18424,19299,14916],{},[18424,19301,19302],{},"Read-heavy config, snapshots",[18408,19304,19305,19309,19312,19314,19322,19324],{},[18424,19306,19307],{},[2968,19308,17073],{},[18424,19310,19311],{},"Set",[18424,19313,19130],{},[18424,19315,19316,2971,19318,2971,19320],{},[2968,19317,3249],{},[2968,19319,13932],{},[2968,19321,11753],{},[18424,19323,14916],{},[18424,19325,19326],{},"Унікальні елементи, snapshots",[18408,19328,19329,19333,19335,19338,19346,19348],{},[18424,19330,19331],{},[2968,19332,17079],{},[18424,19334,19311],{},[18424,19336,19337],{},"Sorted",[18424,19339,19340,2971,19342,2971,19344],{},[2968,19341,3249],{},[2968,19343,13932],{},[2968,19345,11753],{},[18424,19347,14916],{},[18424,19349,19350],{},"Відсортовані унікальні елементи",[18408,19352,19353,19358,19360,19362,19368,19370],{},[18424,19354,19355],{},[2968,19356,19357],{},"ImmutableStack\u003CT>",[18424,19359,19179],{},[18424,19361,19182],{},[18424,19363,19364,2971,19366],{},[2968,19365,10053],{},[2968,19367,16162],{},[18424,19369,19167],{},[18424,19371,19372],{},"Functional LIFO",[18408,19374,19375,19380,19382,19384,19390,19392],{},[18424,19376,19377],{},[2968,19378,19379],{},"ImmutableQueue\u003CT>",[18424,19381,19155],{},[18424,19383,19158],{},[18424,19385,19386,2971,19388],{},[2968,19387,9095],{},[2968,19389,16352],{},[18424,19391,19167],{},[18424,19393,19394],{},"Functional FIFO",[18408,19396,19397,19401,19404,19407,19413,19416],{},[18424,19398,19399],{},[2968,19400,17092],{},[18424,19402,19403],{},"Array",[18424,19405,19406],{},"Index",[18424,19408,19409,2971,19411],{},[2968,19410,14926],{},[2968,19412,14078],{},[18424,19414,19415],{},"O(1) read, O(n) write",[18424,19417,19418],{},"Рідкісні зміни, швидкий доступ",[3032,19420,19422],{"id":19421},"детальне-порівняння-concurrentdictionary-vs-immutabledictionary","Детальне Порівняння: ConcurrentDictionary vs ImmutableDictionary",[2964,19424,19425],{},"Давайте детально порівняємо два найпопулярніші thread-safe словники:",[2964,19427,19428,3490],{},[2977,19429,19125],{},[3044,19431,19433],{"className":3046,"code":19432,"language":3049,"meta":3051,"style":3051},"var dict = new ConcurrentDictionary\u003Cstring, int>();\n\n// ✅ Швидкий запис (O(1) avg, striped locking)\ndict[\"key\"] = 100;\n\n// ✅ Atomic операції\ndict.GetOrAdd(\"key\", k => ExpensiveComputation());\ndict.AddOrUpdate(\"key\", 1, (k, v) => v + 1);\n\n// ⚠️ Ітерація може бачити застарілі дані\nforeach (var kvp in dict)  // Snapshot на момент початку\n{\n    // Інші потоки можуть змінювати dict під час ітерації\n}\n\n// ❌ Не можна отримати \"заморожений\" snapshot\nvar snapshot = dict;  // Це той самий об'єкт, не копія!\n",[2968,19434,19435,19457,19461,19466,19480,19484,19489,19512,19546,19550,19555,19574,19578,19583,19587,19591,19596],{"__ignoreMap":3051},[3055,19436,19437,19439,19441,19443,19445,19447,19449,19451,19453,19455],{"class":3057,"line":3058},[3055,19438,3123],{"class":3122},[3055,19440,3568],{"class":3126},[3055,19442,3130],{"class":3069},[3055,19444,3133],{"class":3122},[3055,19446,4646],{"class":3065},[3055,19448,3139],{"class":3069},[3055,19450,3580],{"class":3122},[3055,19452,2971],{"class":3069},[3055,19454,3142],{"class":3122},[3055,19456,3145],{"class":3069},[3055,19458,19459],{"class":3057,"line":3073},[3055,19460,3116],{"emptyLinePlaceholder":3115},[3055,19462,19463],{"class":3057,"line":3093},[3055,19464,19465],{"class":3156},"// ✅ Швидкий запис (O(1) avg, striped locking)\n",[3055,19467,19468,19470,19472,19474,19476,19478],{"class":3057,"line":3112},[3055,19469,4678],{"class":3126},[3055,19471,3454],{"class":3069},[3055,19473,13515],{"class":3302},[3055,19475,3459],{"class":3069},[3055,19477,4693],{"class":3175},[3055,19479,3070],{"class":3069},[3055,19481,19482],{"class":3057,"line":3119},[3055,19483,3116],{"emptyLinePlaceholder":3115},[3055,19485,19486],{"class":3057,"line":3148},[3055,19487,19488],{"class":3156},"// ✅ Atomic операції\n",[3055,19490,19491,19493,19495,19497,19499,19501,19503,19505,19507,19510],{"class":3057,"line":3153},[3055,19492,4678],{"class":3126},[3055,19494,3080],{"class":3069},[3055,19496,5066],{"class":3168},[3055,19498,3172],{"class":3069},[3055,19500,13515],{"class":3302},[3055,19502,2971],{"class":3069},[3055,19504,5929],{"class":3126},[3055,19506,7560],{"class":3069},[3055,19508,19509],{"class":3168},"ExpensiveComputation",[3055,19511,8173],{"class":3069},[3055,19513,19514,19516,19518,19520,19522,19524,19526,19528,19530,19532,19534,19536,19538,19540,19542,19544],{"class":3057,"line":3160},[3055,19515,4678],{"class":3126},[3055,19517,3080],{"class":3069},[3055,19519,5545],{"class":3168},[3055,19521,3172],{"class":3069},[3055,19523,13515],{"class":3302},[3055,19525,2971],{"class":3069},[3055,19527,3433],{"class":3175},[3055,19529,5653],{"class":3069},[3055,19531,5929],{"class":3126},[3055,19533,2971],{"class":3069},[3055,19535,5934],{"class":3126},[3055,19537,5271],{"class":3069},[3055,19539,5934],{"class":3126},[3055,19541,3261],{"class":3069},[3055,19543,3433],{"class":3175},[3055,19545,3324],{"class":3069},[3055,19547,19548],{"class":3057,"line":3192},[3055,19549,3116],{"emptyLinePlaceholder":3115},[3055,19551,19552],{"class":3057,"line":3198},[3055,19553,19554],{"class":3156},"// ⚠️ Ітерація може бачити застарілі дані\n",[3055,19556,19557,19559,19561,19563,19565,19567,19569,19571],{"class":3057,"line":3235},[3055,19558,5957],{"class":3061},[3055,19560,3204],{"class":3069},[3055,19562,3123],{"class":3122},[3055,19564,5964],{"class":3126},[3055,19566,5967],{"class":3061},[3055,19568,3568],{"class":3126},[3055,19570,3412],{"class":3069},[3055,19572,19573],{"class":3156},"// Snapshot на момент початку\n",[3055,19575,19576],{"class":3057,"line":3241},[3055,19577,3195],{"class":3069},[3055,19579,19580],{"class":3057,"line":3272},[3055,19581,19582],{"class":3156},"    // Інші потоки можуть змінювати dict під час ітерації\n",[3055,19584,19585],{"class":3057,"line":3278},[3055,19586,3484],{"class":3069},[3055,19588,19589],{"class":3057,"line":3284},[3055,19590,3116],{"emptyLinePlaceholder":3115},[3055,19592,19593],{"class":3057,"line":3289},[3055,19594,19595],{"class":3156},"// ❌ Не можна отримати \"заморожений\" snapshot\n",[3055,19597,19598,19600,19602,19604,19606,19608],{"class":3057,"line":3327},[3055,19599,3123],{"class":3122},[3055,19601,18207],{"class":3126},[3055,19603,3130],{"class":3069},[3055,19605,4678],{"class":3126},[3055,19607,3465],{"class":3069},[3055,19609,19610],{"class":3156},"// Це той самий об'єкт, не копія!\n",[2964,19612,19613,3490],{},[2977,19614,14859],{},[3044,19616,19618],{"className":3046,"code":19617,"language":3049,"meta":3051,"style":3051},"var dict = ImmutableDictionary\u003Cstring, int>.Empty;\n\n// ⚠️ Повільніший запис (O(log n), CAS loop)\nImmutableDictionary\u003Cstring, int> original, updated;\ndo\n{\n    original = dict;\n    updated = original.SetItem(\"key\", 100);\n}\nwhile (Interlocked.CompareExchange(ref dict, updated, original) != original);\n\n// ❌ Немає вбудованих atomic операцій (потрібен CAS loop)\n\n// ✅ Ітерація завжди консистентна\nforeach (var kvp in dict)\n{\n    // Ітеруємо immutable snapshot, ніхто не може його змінити\n}\n\n// ✅ Можна отримати справжній snapshot\nvar snapshot = dict;  // Це immutable snapshot, безпечно передавати\n",[2968,19619,19620,19644,19648,19653,19675,19680,19684,19695,19718,19722,19755,19759,19764,19768,19773,19789,19793,19798,19802,19806,19811],{"__ignoreMap":3051},[3055,19621,19622,19624,19626,19628,19630,19632,19634,19636,19638,19640,19642],{"class":3057,"line":3058},[3055,19623,3123],{"class":3122},[3055,19625,3568],{"class":3126},[3055,19627,3130],{"class":3069},[3055,19629,13545],{"class":3126},[3055,19631,3139],{"class":3069},[3055,19633,3580],{"class":3122},[3055,19635,2971],{"class":3069},[3055,19637,3142],{"class":3122},[3055,19639,13556],{"class":3069},[3055,19641,13559],{"class":3126},[3055,19643,3070],{"class":3069},[3055,19645,19646],{"class":3057,"line":3073},[3055,19647,3116],{"emptyLinePlaceholder":3115},[3055,19649,19650],{"class":3057,"line":3093},[3055,19651,19652],{"class":3156},"// ⚠️ Повільніший запис (O(log n), CAS loop)\n",[3055,19654,19655,19657,19659,19661,19663,19665,19667,19669,19671,19673],{"class":3057,"line":3112},[3055,19656,13545],{"class":3065},[3055,19658,3139],{"class":3069},[3055,19660,3580],{"class":3122},[3055,19662,2971],{"class":3069},[3055,19664,3142],{"class":3122},[3055,19666,6325],{"class":3069},[3055,19668,17728],{"class":3126},[3055,19670,2971],{"class":3069},[3055,19672,6160],{"class":3126},[3055,19674,3070],{"class":3069},[3055,19676,19677],{"class":3057,"line":3119},[3055,19678,19679],{"class":3061},"do\n",[3055,19681,19682],{"class":3057,"line":3148},[3055,19683,3195],{"class":3069},[3055,19685,19686,19689,19691,19693],{"class":3057,"line":3153},[3055,19687,19688],{"class":3126},"    original",[3055,19690,3130],{"class":3069},[3055,19692,4678],{"class":3126},[3055,19694,3070],{"class":3069},[3055,19696,19697,19700,19702,19704,19706,19708,19710,19712,19714,19716],{"class":3057,"line":3160},[3055,19698,19699],{"class":3126},"    updated",[3055,19701,3130],{"class":3069},[3055,19703,17728],{"class":3126},[3055,19705,3080],{"class":3069},[3055,19707,14078],{"class":3168},[3055,19709,3172],{"class":3069},[3055,19711,13515],{"class":3302},[3055,19713,2971],{"class":3069},[3055,19715,4693],{"class":3175},[3055,19717,3324],{"class":3069},[3055,19719,19720],{"class":3057,"line":3192},[3055,19721,3484],{"class":3069},[3055,19723,19724,19727,19729,19731,19733,19735,19737,19739,19741,19743,19745,19747,19749,19751,19753],{"class":3057,"line":3198},[3055,19725,19726],{"class":3061},"while",[3055,19728,3204],{"class":3069},[3055,19730,2974],{"class":3126},[3055,19732,3080],{"class":3069},[3055,19734,17795],{"class":3168},[3055,19736,3172],{"class":3069},[3055,19738,17800],{"class":3122},[3055,19740,3568],{"class":3126},[3055,19742,2971],{"class":3069},[3055,19744,6160],{"class":3126},[3055,19746,2971],{"class":3069},[3055,19748,17728],{"class":3126},[3055,19750,17814],{"class":3069},[3055,19752,17728],{"class":3126},[3055,19754,3324],{"class":3069},[3055,19756,19757],{"class":3057,"line":3235},[3055,19758,3116],{"emptyLinePlaceholder":3115},[3055,19760,19761],{"class":3057,"line":3241},[3055,19762,19763],{"class":3156},"// ❌ Немає вбудованих atomic операцій (потрібен CAS loop)\n",[3055,19765,19766],{"class":3057,"line":3272},[3055,19767,3116],{"emptyLinePlaceholder":3115},[3055,19769,19770],{"class":3057,"line":3278},[3055,19771,19772],{"class":3156},"// ✅ Ітерація завжди консистентна\n",[3055,19774,19775,19777,19779,19781,19783,19785,19787],{"class":3057,"line":3284},[3055,19776,5957],{"class":3061},[3055,19778,3204],{"class":3069},[3055,19780,3123],{"class":3122},[3055,19782,5964],{"class":3126},[3055,19784,5967],{"class":3061},[3055,19786,3568],{"class":3126},[3055,19788,3384],{"class":3069},[3055,19790,19791],{"class":3057,"line":3289},[3055,19792,3195],{"class":3069},[3055,19794,19795],{"class":3057,"line":3327},[3055,19796,19797],{"class":3156},"    // Ітеруємо immutable snapshot, ніхто не може його змінити\n",[3055,19799,19800],{"class":3057,"line":3333},[3055,19801,3484],{"class":3069},[3055,19803,19804],{"class":3057,"line":3338},[3055,19805,3116],{"emptyLinePlaceholder":3115},[3055,19807,19808],{"class":3057,"line":3755},[3055,19809,19810],{"class":3156},"// ✅ Можна отримати справжній snapshot\n",[3055,19812,19813,19815,19817,19819,19821,19823],{"class":3057,"line":3760},[3055,19814,3123],{"class":3122},[3055,19816,18207],{"class":3126},[3055,19818,3130],{"class":3069},[3055,19820,4678],{"class":3126},[3055,19822,3465],{"class":3069},[3055,19824,19825],{"class":3156},"// Це immutable snapshot, безпечно передавати\n",[2964,19827,19828,3490],{},[2977,19829,19830],{},"Коли що використовувати",[18281,19832,19833,19863],{},[18284,19834,19836,19857],{"icon":92,"title":19835},"Використовуйте ConcurrentDictionary",[3009,19837,19838,19841,19848,19851,19854],{},[3012,19839,19840],{},"Часті конкурентні записи (>10% операцій)",[3012,19842,19843,19844,2971,19846,18310],{},"Потрібні atomic операції (",[2968,19845,5066],{},[2968,19847,5545],{},[3012,19849,19850],{},"Критична throughput",[3012,19852,19853],{},"Розмір колекції великий (мільйони елементів)",[3012,19855,19856],{},"Не потрібні snapshots",[2964,19858,19859,19862],{},[2977,19860,19861],{},"Приклад",": Кеш з частими оновленнями, лічильники, session storage",[18284,19864,19866,19881],{"icon":793,"title":19865},"Використовуйте ImmutableDictionary",[3009,19867,19868,19871,19873,19875,19878],{},[3012,19869,19870],{},"Рідкісні записи (\u003C10% операцій)",[3012,19872,18390],{},[3012,19874,18393],{},[3012,19876,19877],{},"Версіонування конфігурації",[3012,19879,19880],{},"Безпечна передача між потоками",[2964,19882,19883,19885],{},[2977,19884,19861],{},": Application configuration, feature flags, read-only reference data",[3025,19887],{},[2959,19889,19891],{"id":19890},"практичні-завдання","Практичні Завдання",[3032,19893,19895],{"id":19894},"рівень-1-thread-safe-url-cache","Рівень 1: Thread-Safe URL Cache",[2964,19897,19898,19901],{},[2977,19899,19900],{},"Завдання",": Реалізуйте thread-safe кеш для URL з підтримкою TTL (time-to-live).",[2964,19903,19904,3490],{},[2977,19905,19906],{},"Вимоги",[3009,19908,19909,19915,19918,19928,19934],{},[3012,19910,19911,19912],{},"Використовуйте ",[2968,19913,19914],{},"ConcurrentDictionary\u003Cstring, CacheEntry>",[3012,19916,19917],{},"Кожен запис має TTL (час життя)",[3012,19919,19920,19921,19924,19925,19927],{},"Метод ",[2968,19922,19923],{},"Get(url)"," повертає значення або ",[2968,19926,7147],{}," якщо expired",[3012,19929,19920,19930,19933],{},[2968,19931,19932],{},"Set(url, content, ttl)"," додає/оновлює запис",[3012,19935,19920,19936,19939],{},[2968,19937,19938],{},"CleanupExpired()"," видаляє всі expired записи",[2964,19941,19942,3490],{},[2977,19943,19944],{},"Шаблон",[3044,19946,19949],{"className":3046,"code":19947,"filename":19948,"language":3049,"meta":3050,"style":3051},"using System;\nusing System.Collections.Concurrent;\n\npublic class UrlCache\n{\n    private record CacheEntry(string Content, DateTime ExpiresAt);\n\n    private readonly ConcurrentDictionary\u003Cstring, CacheEntry> _cache = new();\n\n    public string? Get(string url)\n    {\n        // TODO: Реалізуйте\n        throw new NotImplementedException();\n    }\n\n    public void Set(string url, string content, TimeSpan ttl)\n    {\n        // TODO: Реалізуйте\n        throw new NotImplementedException();\n    }\n\n    public int CleanupExpired()\n    {\n        // TODO: Видаліть всі expired записи, поверніть кількість видалених\n        throw new NotImplementedException();\n    }\n}\n\n// Тест:\nvar cache = new UrlCache();\n\nParallel.For(0, 100, i =>\n{\n    string url = $\"https://example.com/page-{i % 10}\";\n    cache.Set(url, $\"Content-{i}\", TimeSpan.FromSeconds(2));\n\n    string? content = cache.Get(url);\n    Console.WriteLine($\"[Thread {i}] {url}: {content}\");\n});\n\nThread.Sleep(3000);  // Чекаємо expiration\nint cleaned = cache.CleanupExpired();\nConsole.WriteLine($\"Cleaned {cleaned} expired entries\");\n","UrlCache.cs",[2968,19950,19951,19959,19975,19979,19988,19992,20015,20019,20045,20049,20069,20073,20078,20090,20094,20098,20127,20131,20135,20145,20149,20153,20164,20168,20173,20183,20187,20191,20195,20200,20215,20219,20241,20245,20270,20311,20315,20338,20377,20381,20385,20403,20421],{"__ignoreMap":3051},[3055,19952,19953,19955,19957],{"class":3057,"line":3058},[3055,19954,3062],{"class":3061},[3055,19956,3066],{"class":3065},[3055,19958,3070],{"class":3069},[3055,19960,19961,19963,19965,19967,19969,19971,19973],{"class":3057,"line":3073},[3055,19962,3062],{"class":3061},[3055,19964,3066],{"class":3065},[3055,19966,3080],{"class":3069},[3055,19968,3083],{"class":3065},[3055,19970,3080],{"class":3069},[3055,19972,6738],{"class":3065},[3055,19974,3070],{"class":3069},[3055,19976,19977],{"class":3057,"line":3093},[3055,19978,3116],{"emptyLinePlaceholder":3115},[3055,19980,19981,19983,19985],{"class":3057,"line":3112},[3055,19982,3367],{"class":3122},[3055,19984,6763],{"class":3122},[3055,19986,19987],{"class":3065}," UrlCache\n",[3055,19989,19990],{"class":3057,"line":3119},[3055,19991,3195],{"class":3069},[3055,19993,19994,19996,19998,20000,20002,20004,20007,20009,20011,20013],{"class":3057,"line":3148},[3055,19995,6799],{"class":3122},[3055,19997,6849],{"class":3122},[3055,19999,6852],{"class":3065},[3055,20001,3172],{"class":3069},[3055,20003,3580],{"class":3122},[3055,20005,20006],{"class":3126}," Content",[3055,20008,2971],{"class":3069},[3055,20010,6864],{"class":3065},[3055,20012,6867],{"class":3126},[3055,20014,3324],{"class":3069},[3055,20016,20017],{"class":3057,"line":3153},[3055,20018,3116],{"emptyLinePlaceholder":3115},[3055,20020,20021,20023,20025,20027,20029,20031,20033,20035,20037,20039,20041,20043],{"class":3057,"line":3160},[3055,20022,6799],{"class":3122},[3055,20024,6802],{"class":3122},[3055,20026,4646],{"class":3065},[3055,20028,3139],{"class":3069},[3055,20030,3580],{"class":3122},[3055,20032,2971],{"class":3069},[3055,20034,6813],{"class":3065},[3055,20036,6325],{"class":3069},[3055,20038,6818],{"class":3126},[3055,20040,3130],{"class":3069},[3055,20042,3133],{"class":3122},[3055,20044,4071],{"class":3069},[3055,20046,20047],{"class":3057,"line":3192},[3055,20048,3116],{"emptyLinePlaceholder":3115},[3055,20050,20051,20053,20055,20057,20060,20062,20064,20067],{"class":3057,"line":3198},[3055,20052,6878],{"class":3122},[3055,20054,9806],{"class":3122},[3055,20056,6940],{"class":3069},[3055,20058,20059],{"class":3168},"Get",[3055,20061,3172],{"class":3069},[3055,20063,3580],{"class":3122},[3055,20065,20066],{"class":3126}," url",[3055,20068,3384],{"class":3069},[3055,20070,20071],{"class":3057,"line":3235},[3055,20072,3238],{"class":3069},[3055,20074,20075],{"class":3057,"line":3241},[3055,20076,20077],{"class":3156},"        // TODO: Реалізуйте\n",[3055,20079,20080,20083,20085,20088],{"class":3057,"line":3272},[3055,20081,20082],{"class":3061},"        throw",[3055,20084,7381],{"class":3122},[3055,20086,20087],{"class":3065}," NotImplementedException",[3055,20089,4071],{"class":3069},[3055,20091,20092],{"class":3057,"line":3278},[3055,20093,3275],{"class":3069},[3055,20095,20096],{"class":3057,"line":3284},[3055,20097,3116],{"emptyLinePlaceholder":3115},[3055,20099,20100,20102,20104,20106,20108,20110,20112,20114,20116,20118,20120,20122,20125],{"class":3057,"line":3289},[3055,20101,6878],{"class":3122},[3055,20103,3370],{"class":3122},[3055,20105,7121],{"class":3168},[3055,20107,3172],{"class":3069},[3055,20109,3580],{"class":3122},[3055,20111,20066],{"class":3126},[3055,20113,2971],{"class":3069},[3055,20115,3580],{"class":3122},[3055,20117,8038],{"class":3126},[3055,20119,2971],{"class":3069},[3055,20121,6885],{"class":3065},[3055,20123,20124],{"class":3126}," ttl",[3055,20126,3384],{"class":3069},[3055,20128,20129],{"class":3057,"line":3327},[3055,20130,3238],{"class":3069},[3055,20132,20133],{"class":3057,"line":3333},[3055,20134,20077],{"class":3156},[3055,20136,20137,20139,20141,20143],{"class":3057,"line":3338},[3055,20138,20082],{"class":3061},[3055,20140,7381],{"class":3122},[3055,20142,20087],{"class":3065},[3055,20144,4071],{"class":3069},[3055,20146,20147],{"class":3057,"line":3755},[3055,20148,3275],{"class":3069},[3055,20150,20151],{"class":3057,"line":3760},[3055,20152,3116],{"emptyLinePlaceholder":3115},[3055,20154,20155,20157,20159,20162],{"class":3057,"line":3797},[3055,20156,6878],{"class":3122},[3055,20158,4909],{"class":3122},[3055,20160,20161],{"class":3168}," CleanupExpired",[3055,20163,17575],{"class":3069},[3055,20165,20166],{"class":3057,"line":3826},[3055,20167,3238],{"class":3069},[3055,20169,20170],{"class":3057,"line":3831},[3055,20171,20172],{"class":3156},"        // TODO: Видаліть всі expired записи, поверніть кількість видалених\n",[3055,20174,20175,20177,20179,20181],{"class":3057,"line":3836},[3055,20176,20082],{"class":3061},[3055,20178,7381],{"class":3122},[3055,20180,20087],{"class":3065},[3055,20182,4071],{"class":3069},[3055,20184,20185],{"class":3057,"line":3842},[3055,20186,3275],{"class":3069},[3055,20188,20189],{"class":3057,"line":3848},[3055,20190,3484],{"class":3069},[3055,20192,20193],{"class":3057,"line":3854},[3055,20194,3116],{"emptyLinePlaceholder":3115},[3055,20196,20197],{"class":3057,"line":4603},[3055,20198,20199],{"class":3156},"// Тест:\n",[3055,20201,20202,20204,20206,20208,20210,20213],{"class":3057,"line":4609},[3055,20203,3123],{"class":3122},[3055,20205,7592],{"class":3126},[3055,20207,3130],{"class":3069},[3055,20209,3133],{"class":3122},[3055,20211,20212],{"class":3065}," UrlCache",[3055,20214,4071],{"class":3069},[3055,20216,20217],{"class":3057,"line":7082},[3055,20218,3116],{"emptyLinePlaceholder":3115},[3055,20220,20221,20223,20225,20227,20229,20231,20233,20235,20237,20239],{"class":3057,"line":7095},[3055,20222,3163],{"class":3126},[3055,20224,3080],{"class":3069},[3055,20226,3169],{"class":3168},[3055,20228,3172],{"class":3069},[3055,20230,3176],{"class":3175},[3055,20232,2971],{"class":3069},[3055,20234,4693],{"class":3175},[3055,20236,2971],{"class":3069},[3055,20238,3186],{"class":3126},[3055,20240,3189],{"class":3069},[3055,20242,20243],{"class":3057,"line":7104},[3055,20244,3195],{"class":3069},[3055,20246,20247,20249,20251,20253,20256,20258,20260,20262,20264,20266,20268],{"class":3057,"line":7109},[3055,20248,5881],{"class":3122},[3055,20250,20066],{"class":3126},[3055,20252,3130],{"class":3069},[3055,20254,20255],{"class":3302},"$\"https://example.com/page-",[3055,20257,3307],{"class":3306},[3055,20259,3186],{"class":3126},[3055,20261,5895],{"class":3069},[3055,20263,5898],{"class":3175},[3055,20265,3318],{"class":3306},[3055,20267,3321],{"class":3302},[3055,20269,3070],{"class":3069},[3055,20271,20272,20275,20277,20279,20281,20284,20286,20289,20291,20293,20295,20297,20299,20301,20303,20305,20307,20309],{"class":3057,"line":7114},[3055,20273,20274],{"class":3126},"    cache",[3055,20276,3080],{"class":3069},[3055,20278,19311],{"class":3168},[3055,20280,3172],{"class":3069},[3055,20282,20283],{"class":3126},"url",[3055,20285,2971],{"class":3069},[3055,20287,20288],{"class":3302},"$\"Content-",[3055,20290,3307],{"class":3306},[3055,20292,3186],{"class":3126},[3055,20294,3318],{"class":3306},[3055,20296,3321],{"class":3302},[3055,20298,2971],{"class":3069},[3055,20300,6885],{"class":3126},[3055,20302,3080],{"class":3069},[3055,20304,7616],{"class":3168},[3055,20306,3172],{"class":3069},[3055,20308,5278],{"class":3175},[3055,20310,7623],{"class":3069},[3055,20312,20313],{"class":3057,"line":7152},[3055,20314,3116],{"emptyLinePlaceholder":3115},[3055,20316,20317,20319,20321,20324,20326,20328,20330,20332,20334,20336],{"class":3057,"line":7157},[3055,20318,5881],{"class":3122},[3055,20320,6940],{"class":3069},[3055,20322,20323],{"class":3126},"content",[3055,20325,3130],{"class":3069},[3055,20327,7707],{"class":3126},[3055,20329,3080],{"class":3069},[3055,20331,20059],{"class":3168},[3055,20333,3172],{"class":3069},[3055,20335,20283],{"class":3126},[3055,20337,3324],{"class":3069},[3055,20339,20340,20342,20344,20346,20348,20350,20352,20354,20356,20359,20361,20363,20365,20367,20369,20371,20373,20375],{"class":3057,"line":7187},[3055,20341,3763],{"class":3126},[3055,20343,3080],{"class":3069},[3055,20345,3297],{"class":3168},[3055,20347,3172],{"class":3069},[3055,20349,7740],{"class":3302},[3055,20351,3307],{"class":3306},[3055,20353,3186],{"class":3126},[3055,20355,3318],{"class":3306},[3055,20357,20358],{"class":3302},"] ",[3055,20360,3307],{"class":3306},[3055,20362,20283],{"class":3126},[3055,20364,3318],{"class":3306},[3055,20366,5292],{"class":3302},[3055,20368,3307],{"class":3306},[3055,20370,20323],{"class":3126},[3055,20372,3318],{"class":3306},[3055,20374,3321],{"class":3302},[3055,20376,3324],{"class":3069},[3055,20378,20379],{"class":3057,"line":7211},[3055,20380,3281],{"class":3069},[3055,20382,20383],{"class":3057,"line":7216},[3055,20384,3116],{"emptyLinePlaceholder":3115},[3055,20386,20387,20389,20391,20393,20395,20398,20400],{"class":3057,"line":7235},[3055,20388,11362],{"class":3126},[3055,20390,3080],{"class":3069},[3055,20392,7770],{"class":3168},[3055,20394,3172],{"class":3069},[3055,20396,20397],{"class":3175},"3000",[3055,20399,3266],{"class":3069},[3055,20401,20402],{"class":3156},"// Чекаємо expiration\n",[3055,20404,20405,20407,20410,20412,20414,20416,20419],{"class":3057,"line":7240},[3055,20406,3142],{"class":3122},[3055,20408,20409],{"class":3126}," cleaned",[3055,20411,3130],{"class":3069},[3055,20413,7707],{"class":3126},[3055,20415,3080],{"class":3069},[3055,20417,20418],{"class":3168},"CleanupExpired",[3055,20420,4071],{"class":3069},[3055,20422,20423,20425,20427,20429,20431,20434,20436,20439,20441,20444],{"class":3057,"line":7245},[3055,20424,3292],{"class":3126},[3055,20426,3080],{"class":3069},[3055,20428,3297],{"class":3168},[3055,20430,3172],{"class":3069},[3055,20432,20433],{"class":3302},"$\"Cleaned ",[3055,20435,3307],{"class":3306},[3055,20437,20438],{"class":3126},"cleaned",[3055,20440,3318],{"class":3306},[3055,20442,20443],{"class":3302}," expired entries\"",[3055,20445,3324],{"class":3069},[2964,20447,20448,20451,20452,20454,20455,2971,20457,20459],{},[2977,20449,20450],{},"Підказка",": Використовуйте ",[2968,20453,4897],{}," + перевірка ",[2968,20456,6995],{},[2968,20458,6599],{}," для cleanup.",[3025,20461],{},[3032,20463,20465],{"id":20464},"рівень-2-log-aggregator-з-blockingcollection","Рівень 2: Log Aggregator з BlockingCollection",[2964,20467,20468,20470],{},[2977,20469,19900],{},": Реалізуйте систему збору логів з кількох джерел у один файл.",[2964,20472,20473,3490],{},[2977,20474,19906],{},[3009,20476,20477,20480,20483,20489],{},[3012,20478,20479],{},"Кілька потоків (producers) генерують лог-повідомлення",[3012,20481,20482],{},"Один потік (consumer) записує їх у файл",[3012,20484,19911,20485,20488],{},[2968,20486,20487],{},"BlockingCollection\u003CLogEntry>"," з bounded capacity",[3012,20490,20491,20492],{},"Підтримка graceful shutdown через ",[2968,20493,12311],{},[2964,20495,20496,3490],{},[2977,20497,19944],{},[3044,20499,20502],{"className":3046,"code":20500,"filename":20501,"language":3049,"meta":3050,"style":3051},"using System;\nusing System.Collections.Concurrent;\nusing System.IO;\nusing System.Threading;\nusing System.Threading.Tasks;\n\npublic record LogEntry(DateTime Timestamp, string Source, string Message);\n\npublic class LogAggregator : IDisposable\n{\n    private readonly BlockingCollection\u003CLogEntry> _logQueue;\n    private readonly Task _writerTask;\n    private readonly string _logFilePath;\n\n    public LogAggregator(string logFilePath, int queueCapacity = 100)\n    {\n        _logFilePath = logFilePath;\n        _logQueue = new BlockingCollection\u003CLogEntry>(queueCapacity);\n        _writerTask = Task.Run(ProcessLogs);\n    }\n\n    public void Log(string source, string message)\n    {\n        // TODO: Додайте LogEntry у чергу\n        throw new NotImplementedException();\n    }\n\n    private void ProcessLogs()\n    {\n        // TODO: Обробляйте логи з GetConsumingEnumerable та пишіть у файл\n        throw new NotImplementedException();\n    }\n\n    public void Dispose()\n    {\n        // TODO: CompleteAdding, дочекайтесь завершення _writerTask\n        throw new NotImplementedException();\n    }\n}\n\n// Тест:\nusing var aggregator = new LogAggregator(\"app.log\");\n\n// 5 producers генерують логи\nvar producers = Enumerable.Range(0, 5).Select(id =>\n    Task.Run(() =>\n    {\n        for (int i = 0; i \u003C 20; i++)\n        {\n            aggregator.Log($\"Source-{id}\", $\"Message {i}\");\n            Thread.Sleep(Random.Shared.Next(10, 50));\n        }\n    })\n).ToArray();\n\nawait Task.WhenAll(producers);\n// Dispose викличе CompleteAdding та дочекається запису всіх логів\n","LogAggregator.cs",[2968,20503,20504,20512,20528,20540,20552,20568,20572,20604,20608,20622,20626,20646,20659,20672,20676,20702,20706,20718,20740,20760,20764,20768,20792,20796,20801,20811,20815,20819,20830,20834,20839,20849,20853,20857,20868,20872,20877,20887,20891,20895,20899,20903,20925,20929,20934,20967,20977,20981,21009,21013,21051,21081,21085,21089,21097,21101,21117],{"__ignoreMap":3051},[3055,20505,20506,20508,20510],{"class":3057,"line":3058},[3055,20507,3062],{"class":3061},[3055,20509,3066],{"class":3065},[3055,20511,3070],{"class":3069},[3055,20513,20514,20516,20518,20520,20522,20524,20526],{"class":3057,"line":3073},[3055,20515,3062],{"class":3061},[3055,20517,3066],{"class":3065},[3055,20519,3080],{"class":3069},[3055,20521,3083],{"class":3065},[3055,20523,3080],{"class":3069},[3055,20525,6738],{"class":3065},[3055,20527,3070],{"class":3069},[3055,20529,20530,20532,20534,20536,20538],{"class":3057,"line":3093},[3055,20531,3062],{"class":3061},[3055,20533,3066],{"class":3065},[3055,20535,3080],{"class":3069},[3055,20537,7912],{"class":3065},[3055,20539,3070],{"class":3069},[3055,20541,20542,20544,20546,20548,20550],{"class":3057,"line":3112},[3055,20543,3062],{"class":3061},[3055,20545,3066],{"class":3065},[3055,20547,3080],{"class":3069},[3055,20549,3102],{"class":3065},[3055,20551,3070],{"class":3069},[3055,20553,20554,20556,20558,20560,20562,20564,20566],{"class":3057,"line":3119},[3055,20555,3062],{"class":3061},[3055,20557,3066],{"class":3065},[3055,20559,3080],{"class":3069},[3055,20561,3102],{"class":3065},[3055,20563,3080],{"class":3069},[3055,20565,3107],{"class":3065},[3055,20567,3070],{"class":3069},[3055,20569,20570],{"class":3057,"line":3148},[3055,20571,3116],{"emptyLinePlaceholder":3115},[3055,20573,20574,20576,20578,20581,20583,20585,20588,20590,20592,20595,20597,20599,20602],{"class":3057,"line":3153},[3055,20575,3367],{"class":3122},[3055,20577,6849],{"class":3122},[3055,20579,20580],{"class":3065}," LogEntry",[3055,20582,3172],{"class":3069},[3055,20584,6864],{"class":3065},[3055,20586,20587],{"class":3126}," Timestamp",[3055,20589,2971],{"class":3069},[3055,20591,3580],{"class":3122},[3055,20593,20594],{"class":3126}," Source",[3055,20596,2971],{"class":3069},[3055,20598,3580],{"class":3122},[3055,20600,20601],{"class":3126}," Message",[3055,20603,3324],{"class":3069},[3055,20605,20606],{"class":3057,"line":3160},[3055,20607,3116],{"emptyLinePlaceholder":3115},[3055,20609,20610,20612,20614,20617,20619],{"class":3057,"line":3192},[3055,20611,3367],{"class":3122},[3055,20613,6763],{"class":3122},[3055,20615,20616],{"class":3065}," LogAggregator",[3055,20618,6787],{"class":3069},[3055,20620,20621],{"class":3065},"IDisposable\n",[3055,20623,20624],{"class":3057,"line":3198},[3055,20625,3195],{"class":3069},[3055,20627,20628,20630,20632,20634,20636,20639,20641,20644],{"class":3057,"line":3235},[3055,20629,6799],{"class":3122},[3055,20631,6802],{"class":3122},[3055,20633,11954],{"class":3065},[3055,20635,3139],{"class":3069},[3055,20637,20638],{"class":3065},"LogEntry",[3055,20640,6325],{"class":3069},[3055,20642,20643],{"class":3126},"_logQueue",[3055,20645,3070],{"class":3069},[3055,20647,20648,20650,20652,20654,20657],{"class":3057,"line":3241},[3055,20649,6799],{"class":3122},[3055,20651,6802],{"class":3122},[3055,20653,9933],{"class":3065},[3055,20655,20656],{"class":3126}," _writerTask",[3055,20658,3070],{"class":3069},[3055,20660,20661,20663,20665,20667,20670],{"class":3057,"line":3272},[3055,20662,6799],{"class":3122},[3055,20664,6802],{"class":3122},[3055,20666,9806],{"class":3122},[3055,20668,20669],{"class":3126}," _logFilePath",[3055,20671,3070],{"class":3069},[3055,20673,20674],{"class":3057,"line":3278},[3055,20675,3116],{"emptyLinePlaceholder":3115},[3055,20677,20678,20680,20682,20684,20686,20689,20691,20693,20696,20698,20700],{"class":3057,"line":3284},[3055,20679,6878],{"class":3122},[3055,20681,20616],{"class":3168},[3055,20683,3172],{"class":3069},[3055,20685,3580],{"class":3122},[3055,20687,20688],{"class":3126}," logFilePath",[3055,20690,2971],{"class":3069},[3055,20692,3142],{"class":3122},[3055,20694,20695],{"class":3126}," queueCapacity",[3055,20697,3130],{"class":3069},[3055,20699,4693],{"class":3175},[3055,20701,3384],{"class":3069},[3055,20703,20704],{"class":3057,"line":3289},[3055,20705,3238],{"class":3069},[3055,20707,20708,20711,20713,20716],{"class":3057,"line":3327},[3055,20709,20710],{"class":3126},"        _logFilePath",[3055,20712,3130],{"class":3069},[3055,20714,20715],{"class":3126},"logFilePath",[3055,20717,3070],{"class":3069},[3055,20719,20720,20723,20725,20727,20729,20731,20733,20735,20738],{"class":3057,"line":3333},[3055,20721,20722],{"class":3126},"        _logQueue",[3055,20724,3130],{"class":3069},[3055,20726,3133],{"class":3122},[3055,20728,11954],{"class":3065},[3055,20730,3139],{"class":3069},[3055,20732,20638],{"class":3065},[3055,20734,7609],{"class":3069},[3055,20736,20737],{"class":3126},"queueCapacity",[3055,20739,3324],{"class":3069},[3055,20741,20742,20745,20747,20749,20751,20753,20755,20758],{"class":3057,"line":3338},[3055,20743,20744],{"class":3126},"        _writerTask",[3055,20746,3130],{"class":3069},[3055,20748,9578],{"class":3126},[3055,20750,3080],{"class":3069},[3055,20752,9583],{"class":3168},[3055,20754,3172],{"class":3069},[3055,20756,20757],{"class":3126},"ProcessLogs",[3055,20759,3324],{"class":3069},[3055,20761,20762],{"class":3057,"line":3755},[3055,20763,3275],{"class":3069},[3055,20765,20766],{"class":3057,"line":3760},[3055,20767,3116],{"emptyLinePlaceholder":3115},[3055,20769,20770,20772,20774,20777,20779,20781,20784,20786,20788,20790],{"class":3057,"line":3797},[3055,20771,6878],{"class":3122},[3055,20773,3370],{"class":3122},[3055,20775,20776],{"class":3168}," Log",[3055,20778,3172],{"class":3069},[3055,20780,3580],{"class":3122},[3055,20782,20783],{"class":3126}," source",[3055,20785,2971],{"class":3069},[3055,20787,3580],{"class":3122},[3055,20789,9635],{"class":3126},[3055,20791,3384],{"class":3069},[3055,20793,20794],{"class":3057,"line":3826},[3055,20795,3238],{"class":3069},[3055,20797,20798],{"class":3057,"line":3831},[3055,20799,20800],{"class":3156},"        // TODO: Додайте LogEntry у чергу\n",[3055,20802,20803,20805,20807,20809],{"class":3057,"line":3836},[3055,20804,20082],{"class":3061},[3055,20806,7381],{"class":3122},[3055,20808,20087],{"class":3065},[3055,20810,4071],{"class":3069},[3055,20812,20813],{"class":3057,"line":3842},[3055,20814,3275],{"class":3069},[3055,20816,20817],{"class":3057,"line":3848},[3055,20818,3116],{"emptyLinePlaceholder":3115},[3055,20820,20821,20823,20825,20828],{"class":3057,"line":3854},[3055,20822,6799],{"class":3122},[3055,20824,3370],{"class":3122},[3055,20826,20827],{"class":3168}," ProcessLogs",[3055,20829,17575],{"class":3069},[3055,20831,20832],{"class":3057,"line":4603},[3055,20833,3238],{"class":3069},[3055,20835,20836],{"class":3057,"line":4609},[3055,20837,20838],{"class":3156},"        // TODO: Обробляйте логи з GetConsumingEnumerable та пишіть у файл\n",[3055,20840,20841,20843,20845,20847],{"class":3057,"line":7082},[3055,20842,20082],{"class":3061},[3055,20844,7381],{"class":3122},[3055,20846,20087],{"class":3065},[3055,20848,4071],{"class":3069},[3055,20850,20851],{"class":3057,"line":7095},[3055,20852,3275],{"class":3069},[3055,20854,20855],{"class":3057,"line":7104},[3055,20856,3116],{"emptyLinePlaceholder":3115},[3055,20858,20859,20861,20863,20866],{"class":3057,"line":7109},[3055,20860,6878],{"class":3122},[3055,20862,3370],{"class":3122},[3055,20864,20865],{"class":3168}," Dispose",[3055,20867,17575],{"class":3069},[3055,20869,20870],{"class":3057,"line":7114},[3055,20871,3238],{"class":3069},[3055,20873,20874],{"class":3057,"line":7152},[3055,20875,20876],{"class":3156},"        // TODO: CompleteAdding, дочекайтесь завершення _writerTask\n",[3055,20878,20879,20881,20883,20885],{"class":3057,"line":7157},[3055,20880,20082],{"class":3061},[3055,20882,7381],{"class":3122},[3055,20884,20087],{"class":3065},[3055,20886,4071],{"class":3069},[3055,20888,20889],{"class":3057,"line":7187},[3055,20890,3275],{"class":3069},[3055,20892,20893],{"class":3057,"line":7211},[3055,20894,3484],{"class":3069},[3055,20896,20897],{"class":3057,"line":7216},[3055,20898,3116],{"emptyLinePlaceholder":3115},[3055,20900,20901],{"class":3057,"line":7235},[3055,20902,20199],{"class":3156},[3055,20904,20905,20907,20909,20912,20914,20916,20918,20920,20923],{"class":3057,"line":7240},[3055,20906,3062],{"class":3061},[3055,20908,6971],{"class":3122},[3055,20910,20911],{"class":3126}," aggregator",[3055,20913,3130],{"class":3069},[3055,20915,3133],{"class":3122},[3055,20917,20616],{"class":3065},[3055,20919,3172],{"class":3069},[3055,20921,20922],{"class":3302},"\"app.log\"",[3055,20924,3324],{"class":3069},[3055,20926,20927],{"class":3057,"line":7245},[3055,20928,3116],{"emptyLinePlaceholder":3115},[3055,20930,20931],{"class":3057,"line":7293},[3055,20932,20933],{"class":3156},"// 5 producers генерують логи\n",[3055,20935,20936,20938,20940,20942,20944,20946,20948,20950,20952,20954,20956,20958,20960,20962,20965],{"class":3057,"line":7298},[3055,20937,3123],{"class":3122},[3055,20939,12853],{"class":3126},[3055,20941,3130],{"class":3069},[3055,20943,12858],{"class":3126},[3055,20945,3080],{"class":3069},[3055,20947,12863],{"class":3168},[3055,20949,3172],{"class":3069},[3055,20951,3176],{"class":3175},[3055,20953,2971],{"class":3069},[3055,20955,11550],{"class":3175},[3055,20957,12874],{"class":3069},[3055,20959,8156],{"class":3168},[3055,20961,3172],{"class":3069},[3055,20963,20964],{"class":3126},"id",[3055,20966,3189],{"class":3069},[3055,20968,20969,20971,20973,20975],{"class":3057,"line":7323},[3055,20970,12888],{"class":3126},[3055,20972,3080],{"class":3069},[3055,20974,9583],{"class":3168},[3055,20976,9586],{"class":3069},[3055,20978,20979],{"class":3057,"line":7328},[3055,20980,3238],{"class":3069},[3055,20982,20983,20985,20987,20989,20991,20993,20995,20997,20999,21001,21003,21005,21007],{"class":3057,"line":7353},[3055,20984,3636],{"class":3061},[3055,20986,3204],{"class":3069},[3055,20988,3142],{"class":3122},[3055,20990,5444],{"class":3126},[3055,20992,3130],{"class":3069},[3055,20994,3176],{"class":3175},[3055,20996,3216],{"class":3069},[3055,20998,3186],{"class":3126},[3055,21000,3222],{"class":3069},[3055,21002,10321],{"class":3175},[3055,21004,3216],{"class":3069},[3055,21006,3186],{"class":3126},[3055,21008,3232],{"class":3069},[3055,21010,21011],{"class":3057,"line":7358},[3055,21012,3665],{"class":3069},[3055,21014,21015,21018,21020,21023,21025,21028,21030,21032,21034,21036,21038,21041,21043,21045,21047,21049],{"class":3057,"line":7376},[3055,21016,21017],{"class":3126},"            aggregator",[3055,21019,3080],{"class":3069},[3055,21021,21022],{"class":3168},"Log",[3055,21024,3172],{"class":3069},[3055,21026,21027],{"class":3302},"$\"Source-",[3055,21029,3307],{"class":3306},[3055,21031,20964],{"class":3126},[3055,21033,3318],{"class":3306},[3055,21035,3321],{"class":3302},[3055,21037,2971],{"class":3069},[3055,21039,21040],{"class":3302},"$\"Message ",[3055,21042,3307],{"class":3306},[3055,21044,3186],{"class":3126},[3055,21046,3318],{"class":3306},[3055,21048,3321],{"class":3302},[3055,21050,3324],{"class":3069},[3055,21052,21053,21055,21057,21059,21061,21063,21065,21067,21069,21071,21073,21075,21077,21079],{"class":3057,"line":7396},[3055,21054,9844],{"class":3126},[3055,21056,3080],{"class":3069},[3055,21058,7770],{"class":3168},[3055,21060,3172],{"class":3069},[3055,21062,9706],{"class":3126},[3055,21064,3080],{"class":3069},[3055,21066,9711],{"class":3126},[3055,21068,3080],{"class":3069},[3055,21070,9716],{"class":3168},[3055,21072,3172],{"class":3069},[3055,21074,3181],{"class":3175},[3055,21076,2971],{"class":3069},[3055,21078,5295],{"class":3175},[3055,21080,7623],{"class":3069},[3055,21082,21083],{"class":3057,"line":7402},[3055,21084,3728],{"class":3069},[3055,21086,21087],{"class":3057,"line":7407},[3055,21088,13060],{"class":3069},[3055,21090,21091,21093,21095],{"class":3057,"line":7413},[3055,21092,12874],{"class":3069},[3055,21094,11525],{"class":3168},[3055,21096,4071],{"class":3069},[3055,21098,21099],{"class":3057,"line":7437},[3055,21100,3116],{"emptyLinePlaceholder":3115},[3055,21102,21103,21105,21107,21109,21111,21113,21115],{"class":3057,"line":7442},[3055,21104,9930],{"class":3122},[3055,21106,9933],{"class":3126},[3055,21108,3080],{"class":3069},[3055,21110,9971],{"class":3168},[3055,21112,3172],{"class":3069},[3055,21114,13113],{"class":3126},[3055,21116,3324],{"class":3069},[3055,21118,21119],{"class":3057,"line":7448},[3055,21120,21121],{"class":3156},"// Dispose викличе CompleteAdding та дочекається запису всіх логів\n",[2964,21123,21124,21126,21127,21129,21130,9445,21132,11025,21135,3080],{},[2977,21125,20450],{},": У ",[2968,21128,20757],{}," використовуйте ",[2968,21131,12299],{},[2968,21133,21134],{},"File.AppendAllText()",[2968,21136,21137],{},"StreamWriter",[3025,21139],{},[3032,21141,21143],{"id":21142},"рівень-3-concurrent-web-crawler-з-concurrentdictionary","Рівень 3: Concurrent Web Crawler з ConcurrentDictionary",[2964,21145,21146,21148],{},[2977,21147,19900],{},": Реалізуйте багатопотоковий web crawler що обходить сайт та збирає всі унікальні URL.",[2964,21150,21151,3490],{},[2977,21152,19906],{},[3009,21154,21155,21161,21167,21170,21173],{},[3012,21156,19911,21157,21160],{},[2968,21158,21159],{},"ConcurrentDictionary\u003Cstring, bool>"," для відстеження відвіданих URL",[3012,21162,19911,21163,21166],{},[2968,21164,21165],{},"ConcurrentQueue\u003Cstring>"," для черги URL що потрібно обробити",[3012,21168,21169],{},"Кілька worker потоків обробляють URL паралельно",[3012,21171,21172],{},"Уникайте дублікатів (не відвідуємо один URL двічі)",[3012,21174,21175],{},"Обмеження глибини (depth limit)",[2964,21177,21178,3490],{},[2977,21179,19944],{},[3044,21181,21184],{"className":3046,"code":21182,"filename":21183,"language":3049,"meta":3050,"style":3051},"using System;\nusing System.Collections.Concurrent;\nusing System.Text.RegularExpressions;\nusing System.Threading;\nusing System.Threading.Tasks;\n\npublic class WebCrawler\n{\n    private readonly ConcurrentDictionary\u003Cstring, bool> _visited = new();\n    private readonly ConcurrentQueue\u003C(string Url, int Depth)> _queue = new();\n    private readonly int _maxDepth;\n    private readonly int _workerCount;\n    private int _activeWorkers;\n\n    public WebCrawler(int maxDepth = 3, int workerCount = 4)\n    {\n        _maxDepth = maxDepth;\n        _workerCount = workerCount;\n    }\n\n    public async Task\u003CList\u003Cstring>> CrawlAsync(string startUrl)\n    {\n        _queue.Enqueue((startUrl, 0));\n        _activeWorkers = _workerCount;\n\n        var workers = Enumerable.Range(0, _workerCount)\n            .Select(id => Task.Run(() => WorkerLoop(id)))\n            .ToArray();\n\n        await Task.WhenAll(workers);\n\n        return _visited.Keys.ToList();\n    }\n\n    private void WorkerLoop(int workerId)\n    {\n        while (true)\n        {\n            if (_queue.TryDequeue(out var item))\n            {\n                var (url, depth) = item;\n\n                // TODO: Перевірте чи URL вже відвіданий через TryAdd\n                // TODO: Якщо depth \u003C _maxDepth, \"завантажте\" сторінку та додайте нові URL у чергу\n                // TODO: Симулюйте завантаження через Thread.Sleep(100)\n\n                Console.WriteLine($\"[Worker {workerId}] Crawled: {url} (depth {depth})\");\n            }\n            else\n            {\n                // Черга порожня — перевіряємо чи всі workers idle\n                if (Interlocked.Decrement(ref _activeWorkers) == 0)\n                {\n                    // Всі workers idle та черга порожня → завершуємо\n                    break;\n                }\n\n                // Чекаємо трохи, можливо інший worker додасть URL\n                Thread.Sleep(50);\n                Interlocked.Increment(ref _activeWorkers);\n            }\n        }\n    }\n\n    private List\u003Cstring> ExtractLinks(string url)\n    {\n        // Симуляція парсингу HTML та витягування посилань\n        var baseUrl = new Uri(url).GetLeftPart(UriPartial.Authority);\n        return Enumerable.Range(1, Random.Shared.Next(2, 5))\n            .Select(i => $\"{baseUrl}/page-{Random.Shared.Next(1, 20)}\")\n            .ToList();\n    }\n}\n\n// Тест:\nvar crawler = new WebCrawler(maxDepth: 2, workerCount: 3);\nvar visitedUrls = await crawler.CrawlAsync(\"https://example.com\");\n\nConsole.WriteLine($\"\\nTotal URLs crawled: {visitedUrls.Count}\");\nforeach (var url in visitedUrls.Take(10))\n{\n    Console.WriteLine($\"  - {url}\");\n}\n","WebCrawler.cs",[2968,21185,21186,21194,21210,21228,21240,21256,21260,21269,21273,21300,21335,21348,21361,21372,21376,21407,21411,21423,21435,21439,21443,21474,21478,21499,21511,21515,21540,21570,21578,21582,21600,21604,21623,21627,21631,21649,21653,21663,21667,21689,21693,21714,21718,21723,21728,21733,21737,21781,21785,21790,21794,21799,21826,21831,21836,21843,21848,21852,21857,21872,21890,21894,21898,21902,21906,21929,21933,21938,21973,22010,22060,22068,22072,22076,22080,22084,22115,22139,22143,22175,22199,22203,22225],{"__ignoreMap":3051},[3055,21187,21188,21190,21192],{"class":3057,"line":3058},[3055,21189,3062],{"class":3061},[3055,21191,3066],{"class":3065},[3055,21193,3070],{"class":3069},[3055,21195,21196,21198,21200,21202,21204,21206,21208],{"class":3057,"line":3073},[3055,21197,3062],{"class":3061},[3055,21199,3066],{"class":3065},[3055,21201,3080],{"class":3069},[3055,21203,3083],{"class":3065},[3055,21205,3080],{"class":3069},[3055,21207,6738],{"class":3065},[3055,21209,3070],{"class":3069},[3055,21211,21212,21214,21216,21218,21221,21223,21226],{"class":3057,"line":3093},[3055,21213,3062],{"class":3061},[3055,21215,3066],{"class":3065},[3055,21217,3080],{"class":3069},[3055,21219,21220],{"class":3065},"Text",[3055,21222,3080],{"class":3069},[3055,21224,21225],{"class":3065},"RegularExpressions",[3055,21227,3070],{"class":3069},[3055,21229,21230,21232,21234,21236,21238],{"class":3057,"line":3112},[3055,21231,3062],{"class":3061},[3055,21233,3066],{"class":3065},[3055,21235,3080],{"class":3069},[3055,21237,3102],{"class":3065},[3055,21239,3070],{"class":3069},[3055,21241,21242,21244,21246,21248,21250,21252,21254],{"class":3057,"line":3119},[3055,21243,3062],{"class":3061},[3055,21245,3066],{"class":3065},[3055,21247,3080],{"class":3069},[3055,21249,3102],{"class":3065},[3055,21251,3080],{"class":3069},[3055,21253,3107],{"class":3065},[3055,21255,3070],{"class":3069},[3055,21257,21258],{"class":3057,"line":3148},[3055,21259,3116],{"emptyLinePlaceholder":3115},[3055,21261,21262,21264,21266],{"class":3057,"line":3153},[3055,21263,3367],{"class":3122},[3055,21265,6763],{"class":3122},[3055,21267,21268],{"class":3065}," WebCrawler\n",[3055,21270,21271],{"class":3057,"line":3160},[3055,21272,3195],{"class":3069},[3055,21274,21275,21277,21279,21281,21283,21285,21287,21289,21291,21294,21296,21298],{"class":3057,"line":3192},[3055,21276,6799],{"class":3122},[3055,21278,6802],{"class":3122},[3055,21280,4646],{"class":3065},[3055,21282,3139],{"class":3069},[3055,21284,3580],{"class":3122},[3055,21286,2971],{"class":3069},[3055,21288,4670],{"class":3122},[3055,21290,6325],{"class":3069},[3055,21292,21293],{"class":3126},"_visited",[3055,21295,3130],{"class":3069},[3055,21297,3133],{"class":3122},[3055,21299,4071],{"class":3069},[3055,21301,21302,21304,21306,21308,21311,21313,21316,21318,21320,21323,21326,21329,21331,21333],{"class":3057,"line":3198},[3055,21303,6799],{"class":3122},[3055,21305,6802],{"class":3122},[3055,21307,9166],{"class":3065},[3055,21309,21310],{"class":3069},"\u003C(",[3055,21312,3580],{"class":3122},[3055,21314,21315],{"class":3126}," Url",[3055,21317,2971],{"class":3069},[3055,21319,3142],{"class":3122},[3055,21321,21322],{"class":3126}," Depth",[3055,21324,21325],{"class":3069},")> ",[3055,21327,21328],{"class":3126},"_queue",[3055,21330,3130],{"class":3069},[3055,21332,3133],{"class":3122},[3055,21334,4071],{"class":3069},[3055,21336,21337,21339,21341,21343,21346],{"class":3057,"line":3235},[3055,21338,6799],{"class":3122},[3055,21340,6802],{"class":3122},[3055,21342,4909],{"class":3122},[3055,21344,21345],{"class":3126}," _maxDepth",[3055,21347,3070],{"class":3069},[3055,21349,21350,21352,21354,21356,21359],{"class":3057,"line":3241},[3055,21351,6799],{"class":3122},[3055,21353,6802],{"class":3122},[3055,21355,4909],{"class":3122},[3055,21357,21358],{"class":3126}," _workerCount",[3055,21360,3070],{"class":3069},[3055,21362,21363,21365,21367,21370],{"class":3057,"line":3272},[3055,21364,6799],{"class":3122},[3055,21366,4909],{"class":3122},[3055,21368,21369],{"class":3126}," _activeWorkers",[3055,21371,3070],{"class":3069},[3055,21373,21374],{"class":3057,"line":3278},[3055,21375,3116],{"emptyLinePlaceholder":3115},[3055,21377,21378,21380,21383,21385,21387,21390,21392,21394,21396,21398,21401,21403,21405],{"class":3057,"line":3284},[3055,21379,6878],{"class":3122},[3055,21381,21382],{"class":3168}," WebCrawler",[3055,21384,3172],{"class":3069},[3055,21386,3142],{"class":3122},[3055,21388,21389],{"class":3126}," maxDepth",[3055,21391,3130],{"class":3069},[3055,21393,9223],{"class":3175},[3055,21395,2971],{"class":3069},[3055,21397,3142],{"class":3122},[3055,21399,21400],{"class":3126}," workerCount",[3055,21402,3130],{"class":3069},[3055,21404,14249],{"class":3175},[3055,21406,3384],{"class":3069},[3055,21408,21409],{"class":3057,"line":3289},[3055,21410,3238],{"class":3069},[3055,21412,21413,21416,21418,21421],{"class":3057,"line":3327},[3055,21414,21415],{"class":3126},"        _maxDepth",[3055,21417,3130],{"class":3069},[3055,21419,21420],{"class":3126},"maxDepth",[3055,21422,3070],{"class":3069},[3055,21424,21425,21428,21430,21433],{"class":3057,"line":3333},[3055,21426,21427],{"class":3126},"        _workerCount",[3055,21429,3130],{"class":3069},[3055,21431,21432],{"class":3126},"workerCount",[3055,21434,3070],{"class":3069},[3055,21436,21437],{"class":3057,"line":3338},[3055,21438,3275],{"class":3069},[3055,21440,21441],{"class":3057,"line":3755},[3055,21442,3116],{"emptyLinePlaceholder":3115},[3055,21444,21445,21447,21450,21452,21454,21456,21458,21460,21462,21465,21467,21469,21472],{"class":3057,"line":3760},[3055,21446,6878],{"class":3122},[3055,21448,21449],{"class":3122}," async",[3055,21451,9933],{"class":3065},[3055,21453,3139],{"class":3069},[3055,21455,19264],{"class":3065},[3055,21457,3139],{"class":3069},[3055,21459,3580],{"class":3122},[3055,21461,10577],{"class":3069},[3055,21463,21464],{"class":3168},"CrawlAsync",[3055,21466,3172],{"class":3069},[3055,21468,3580],{"class":3122},[3055,21470,21471],{"class":3126}," startUrl",[3055,21473,3384],{"class":3069},[3055,21475,21476],{"class":3057,"line":3797},[3055,21477,3238],{"class":3069},[3055,21479,21480,21483,21485,21487,21490,21493,21495,21497],{"class":3057,"line":3826},[3055,21481,21482],{"class":3126},"        _queue",[3055,21484,3080],{"class":3069},[3055,21486,9095],{"class":3168},[3055,21488,21489],{"class":3069},"((",[3055,21491,21492],{"class":3126},"startUrl",[3055,21494,2971],{"class":3069},[3055,21496,3176],{"class":3175},[3055,21498,7623],{"class":3069},[3055,21500,21501,21504,21506,21509],{"class":3057,"line":3831},[3055,21502,21503],{"class":3126},"        _activeWorkers",[3055,21505,3130],{"class":3069},[3055,21507,21508],{"class":3126},"_workerCount",[3055,21510,3070],{"class":3069},[3055,21512,21513],{"class":3057,"line":3836},[3055,21514,3116],{"emptyLinePlaceholder":3115},[3055,21516,21517,21519,21522,21524,21526,21528,21530,21532,21534,21536,21538],{"class":3057,"line":3842},[3055,21518,7160],{"class":3122},[3055,21520,21521],{"class":3126}," workers",[3055,21523,3130],{"class":3069},[3055,21525,12858],{"class":3126},[3055,21527,3080],{"class":3069},[3055,21529,12863],{"class":3168},[3055,21531,3172],{"class":3069},[3055,21533,3176],{"class":3175},[3055,21535,2971],{"class":3069},[3055,21537,21508],{"class":3126},[3055,21539,3384],{"class":3069},[3055,21541,21542,21544,21546,21548,21550,21552,21554,21556,21558,21561,21564,21566,21568],{"class":3057,"line":3848},[3055,21543,8072],{"class":3069},[3055,21545,8156],{"class":3168},[3055,21547,3172],{"class":3069},[3055,21549,20964],{"class":3126},[3055,21551,7560],{"class":3069},[3055,21553,9578],{"class":3126},[3055,21555,3080],{"class":3069},[3055,21557,9583],{"class":3168},[3055,21559,21560],{"class":3069},"(() => ",[3055,21562,21563],{"class":3168},"WorkerLoop",[3055,21565,3172],{"class":3069},[3055,21567,20964],{"class":3126},[3055,21569,12165],{"class":3069},[3055,21571,21572,21574,21576],{"class":3057,"line":3854},[3055,21573,8072],{"class":3069},[3055,21575,11525],{"class":3168},[3055,21577,4071],{"class":3069},[3055,21579,21580],{"class":3057,"line":4603},[3055,21581,3116],{"emptyLinePlaceholder":3115},[3055,21583,21584,21587,21589,21591,21593,21595,21598],{"class":3057,"line":4609},[3055,21585,21586],{"class":3122},"        await",[3055,21588,9933],{"class":3126},[3055,21590,3080],{"class":3069},[3055,21592,9971],{"class":3168},[3055,21594,3172],{"class":3069},[3055,21596,21597],{"class":3126},"workers",[3055,21599,3324],{"class":3069},[3055,21601,21602],{"class":3057,"line":7082},[3055,21603,3116],{"emptyLinePlaceholder":3115},[3055,21605,21606,21608,21611,21613,21616,21618,21621],{"class":3057,"line":7095},[3055,21607,5441],{"class":3061},[3055,21609,21610],{"class":3126}," _visited",[3055,21612,3080],{"class":3069},[3055,21614,21615],{"class":3126},"Keys",[3055,21617,3080],{"class":3069},[3055,21619,21620],{"class":3168},"ToList",[3055,21622,4071],{"class":3069},[3055,21624,21625],{"class":3057,"line":7104},[3055,21626,3275],{"class":3069},[3055,21628,21629],{"class":3057,"line":7109},[3055,21630,3116],{"emptyLinePlaceholder":3115},[3055,21632,21633,21635,21637,21640,21642,21644,21647],{"class":3057,"line":7114},[3055,21634,6799],{"class":3122},[3055,21636,3370],{"class":3122},[3055,21638,21639],{"class":3168}," WorkerLoop",[3055,21641,3172],{"class":3069},[3055,21643,3142],{"class":3122},[3055,21645,21646],{"class":3126}," workerId",[3055,21648,3384],{"class":3069},[3055,21650,21651],{"class":3057,"line":7152},[3055,21652,3238],{"class":3069},[3055,21654,21655,21657,21659,21661],{"class":3057,"line":7157},[3055,21656,17786],{"class":3061},[3055,21658,3204],{"class":3069},[3055,21660,6358],{"class":3122},[3055,21662,3384],{"class":3069},[3055,21664,21665],{"class":3057,"line":7187},[3055,21666,3665],{"class":3069},[3055,21668,21669,21671,21673,21675,21677,21679,21681,21683,21685,21687],{"class":3057,"line":7211},[3055,21670,6985],{"class":3061},[3055,21672,3204],{"class":3069},[3055,21674,21328],{"class":3126},[3055,21676,3080],{"class":3069},[3055,21678,9105],{"class":3168},[3055,21680,3172],{"class":3069},[3055,21682,4906],{"class":3122},[3055,21684,6971],{"class":3122},[3055,21686,3381],{"class":3126},[3055,21688,4915],{"class":3069},[3055,21690,21691],{"class":3057,"line":7216},[3055,21692,7012],{"class":3069},[3055,21694,21695,21698,21700,21702,21704,21707,21710,21712],{"class":3057,"line":7235},[3055,21696,21697],{"class":3122},"                var",[3055,21699,3204],{"class":3069},[3055,21701,20283],{"class":3126},[3055,21703,2971],{"class":3069},[3055,21705,21706],{"class":3126},"depth",[3055,21708,21709],{"class":3069},") = ",[3055,21711,3462],{"class":3126},[3055,21713,3070],{"class":3069},[3055,21715,21716],{"class":3057,"line":7240},[3055,21717,3116],{"emptyLinePlaceholder":3115},[3055,21719,21720],{"class":3057,"line":7245},[3055,21721,21722],{"class":3156},"                // TODO: Перевірте чи URL вже відвіданий через TryAdd\n",[3055,21724,21725],{"class":3057,"line":7293},[3055,21726,21727],{"class":3156},"                // TODO: Якщо depth \u003C _maxDepth, \"завантажте\" сторінку та додайте нові URL у чергу\n",[3055,21729,21730],{"class":3057,"line":7298},[3055,21731,21732],{"class":3156},"                // TODO: Симулюйте завантаження через Thread.Sleep(100)\n",[3055,21734,21735],{"class":3057,"line":7323},[3055,21736,3116],{"emptyLinePlaceholder":3115},[3055,21738,21739,21742,21744,21746,21748,21751,21753,21756,21758,21761,21763,21765,21767,21770,21772,21774,21776,21779],{"class":3057,"line":7328},[3055,21740,21741],{"class":3126},"                Console",[3055,21743,3080],{"class":3069},[3055,21745,3297],{"class":3168},[3055,21747,3172],{"class":3069},[3055,21749,21750],{"class":3302},"$\"[Worker ",[3055,21752,3307],{"class":3306},[3055,21754,21755],{"class":3126},"workerId",[3055,21757,3318],{"class":3306},[3055,21759,21760],{"class":3302},"] Crawled: ",[3055,21762,3307],{"class":3306},[3055,21764,20283],{"class":3126},[3055,21766,3318],{"class":3306},[3055,21768,21769],{"class":3302}," (depth ",[3055,21771,3307],{"class":3306},[3055,21773,21706],{"class":3126},[3055,21775,3318],{"class":3306},[3055,21777,21778],{"class":3302},")\"",[3055,21780,3324],{"class":3069},[3055,21782,21783],{"class":3057,"line":7353},[3055,21784,7041],{"class":3069},[3055,21786,21787],{"class":3057,"line":7358},[3055,21788,21789],{"class":3061},"            else\n",[3055,21791,21792],{"class":3057,"line":7376},[3055,21793,7012],{"class":3069},[3055,21795,21796],{"class":3057,"line":7396},[3055,21797,21798],{"class":3156},"                // Черга порожня — перевіряємо чи всі workers idle\n",[3055,21800,21801,21804,21806,21808,21810,21813,21815,21817,21819,21822,21824],{"class":3057,"line":7402},[3055,21802,21803],{"class":3061},"                if",[3055,21805,3204],{"class":3069},[3055,21807,2974],{"class":3126},[3055,21809,3080],{"class":3069},[3055,21811,21812],{"class":3168},"Decrement",[3055,21814,3172],{"class":3069},[3055,21816,17800],{"class":3122},[3055,21818,21369],{"class":3126},[3055,21820,21821],{"class":3069},") == ",[3055,21823,3176],{"class":3175},[3055,21825,3384],{"class":3069},[3055,21827,21828],{"class":3057,"line":7407},[3055,21829,21830],{"class":3069},"                {\n",[3055,21832,21833],{"class":3057,"line":7413},[3055,21834,21835],{"class":3156},"                    // Всі workers idle та черга порожня → завершуємо\n",[3055,21837,21838,21841],{"class":3057,"line":7437},[3055,21839,21840],{"class":3061},"                    break",[3055,21842,3070],{"class":3069},[3055,21844,21845],{"class":3057,"line":7442},[3055,21846,21847],{"class":3069},"                }\n",[3055,21849,21850],{"class":3057,"line":7448},[3055,21851,3116],{"emptyLinePlaceholder":3115},[3055,21853,21854],{"class":3057,"line":7469},[3055,21855,21856],{"class":3156},"                // Чекаємо трохи, можливо інший worker додасть URL\n",[3055,21858,21859,21862,21864,21866,21868,21870],{"class":3057,"line":7490},[3055,21860,21861],{"class":3126},"                Thread",[3055,21863,3080],{"class":3069},[3055,21865,7770],{"class":3168},[3055,21867,3172],{"class":3069},[3055,21869,5295],{"class":3175},[3055,21871,3324],{"class":3069},[3055,21873,21874,21877,21879,21882,21884,21886,21888],{"class":3057,"line":7495},[3055,21875,21876],{"class":3126},"                Interlocked",[3055,21878,3080],{"class":3069},[3055,21880,21881],{"class":3168},"Increment",[3055,21883,3172],{"class":3069},[3055,21885,17800],{"class":3122},[3055,21887,21369],{"class":3126},[3055,21889,3324],{"class":3069},[3055,21891,21892],{"class":3057,"line":7500},[3055,21893,7041],{"class":3069},[3055,21895,21896],{"class":3057,"line":7513},[3055,21897,3728],{"class":3069},[3055,21899,21900],{"class":3057,"line":7518},[3055,21901,3275],{"class":3069},[3055,21903,21904],{"class":3057,"line":7523},[3055,21905,3116],{"emptyLinePlaceholder":3115},[3055,21907,21908,21910,21912,21914,21916,21918,21921,21923,21925,21927],{"class":3057,"line":7545},[3055,21909,6799],{"class":3122},[3055,21911,3136],{"class":3065},[3055,21913,3139],{"class":3069},[3055,21915,3580],{"class":3122},[3055,21917,6325],{"class":3069},[3055,21919,21920],{"class":3168},"ExtractLinks",[3055,21922,3172],{"class":3069},[3055,21924,3580],{"class":3122},[3055,21926,20066],{"class":3126},[3055,21928,3384],{"class":3069},[3055,21930,21931],{"class":3057,"line":7550},[3055,21932,3238],{"class":3069},[3055,21934,21935],{"class":3057,"line":7571},[3055,21936,21937],{"class":3156},"        // Симуляція парсингу HTML та витягування посилань\n",[3055,21939,21940,21942,21945,21947,21949,21952,21954,21956,21958,21961,21963,21966,21968,21971],{"class":3057,"line":7576},[3055,21941,7160],{"class":3122},[3055,21943,21944],{"class":3126}," baseUrl",[3055,21946,3130],{"class":3069},[3055,21948,3133],{"class":3122},[3055,21950,21951],{"class":3065}," Uri",[3055,21953,3172],{"class":3069},[3055,21955,20283],{"class":3126},[3055,21957,12874],{"class":3069},[3055,21959,21960],{"class":3168},"GetLeftPart",[3055,21962,3172],{"class":3069},[3055,21964,21965],{"class":3126},"UriPartial",[3055,21967,3080],{"class":3069},[3055,21969,21970],{"class":3126},"Authority",[3055,21972,3324],{"class":3069},[3055,21974,21975,21977,21980,21982,21984,21986,21988,21990,21992,21994,21996,21998,22000,22002,22004,22006,22008],{"class":3057,"line":7581},[3055,21976,5441],{"class":3061},[3055,21978,21979],{"class":3126}," Enumerable",[3055,21981,3080],{"class":3069},[3055,21983,12863],{"class":3168},[3055,21985,3172],{"class":3069},[3055,21987,3433],{"class":3175},[3055,21989,2971],{"class":3069},[3055,21991,9706],{"class":3126},[3055,21993,3080],{"class":3069},[3055,21995,9711],{"class":3126},[3055,21997,3080],{"class":3069},[3055,21999,9716],{"class":3168},[3055,22001,3172],{"class":3069},[3055,22003,5278],{"class":3175},[3055,22005,2971],{"class":3069},[3055,22007,11550],{"class":3175},[3055,22009,4915],{"class":3069},[3055,22011,22012,22014,22016,22018,22020,22022,22024,22026,22029,22031,22034,22036,22038,22040,22042,22044,22046,22048,22050,22052,22054,22056,22058],{"class":3057,"line":7587},[3055,22013,8072],{"class":3069},[3055,22015,8156],{"class":3168},[3055,22017,3172],{"class":3069},[3055,22019,3186],{"class":3126},[3055,22021,7560],{"class":3069},[3055,22023,5988],{"class":3302},[3055,22025,3307],{"class":3306},[3055,22027,22028],{"class":3126},"baseUrl",[3055,22030,3318],{"class":3306},[3055,22032,22033],{"class":3302},"/page-",[3055,22035,3307],{"class":3306},[3055,22037,9706],{"class":3126},[3055,22039,3080],{"class":3306},[3055,22041,9711],{"class":3126},[3055,22043,3080],{"class":3306},[3055,22045,9716],{"class":3168},[3055,22047,3172],{"class":3306},[3055,22049,3433],{"class":3175},[3055,22051,2971],{"class":3306},[3055,22053,10321],{"class":3175},[3055,22055,8726],{"class":3306},[3055,22057,3321],{"class":3302},[3055,22059,3384],{"class":3069},[3055,22061,22062,22064,22066],{"class":3057,"line":7626},[3055,22063,8072],{"class":3069},[3055,22065,21620],{"class":3168},[3055,22067,4071],{"class":3069},[3055,22069,22070],{"class":3057,"line":7631},[3055,22071,3275],{"class":3069},[3055,22073,22074],{"class":3057,"line":7637},[3055,22075,3484],{"class":3069},[3055,22077,22078],{"class":3057,"line":7660},[3055,22079,3116],{"emptyLinePlaceholder":3115},[3055,22081,22082],{"class":3057,"line":7665},[3055,22083,20199],{"class":3156},[3055,22085,22086,22088,22091,22093,22095,22097,22099,22101,22103,22105,22107,22109,22111,22113],{"class":3057,"line":7693},[3055,22087,3123],{"class":3122},[3055,22089,22090],{"class":3126}," crawler",[3055,22092,3130],{"class":3069},[3055,22094,3133],{"class":3122},[3055,22096,21382],{"class":3065},[3055,22098,3172],{"class":3069},[3055,22100,21420],{"class":3126},[3055,22102,5292],{"class":3069},[3055,22104,5278],{"class":3175},[3055,22106,2971],{"class":3069},[3055,22108,21432],{"class":3126},[3055,22110,5292],{"class":3069},[3055,22112,9223],{"class":3175},[3055,22114,3324],{"class":3069},[3055,22116,22117,22119,22122,22124,22126,22128,22130,22132,22134,22137],{"class":3057,"line":7698},[3055,22118,3123],{"class":3122},[3055,22120,22121],{"class":3126}," visitedUrls",[3055,22123,3130],{"class":3069},[3055,22125,9930],{"class":3122},[3055,22127,22090],{"class":3126},[3055,22129,3080],{"class":3069},[3055,22131,21464],{"class":3168},[3055,22133,3172],{"class":3069},[3055,22135,22136],{"class":3302},"\"https://example.com\"",[3055,22138,3324],{"class":3069},[3055,22140,22141],{"class":3057,"line":7724},[3055,22142,3116],{"emptyLinePlaceholder":3115},[3055,22144,22145,22147,22149,22151,22153,22155,22157,22160,22162,22165,22167,22169,22171,22173],{"class":3057,"line":7729},[3055,22146,3292],{"class":3126},[3055,22148,3080],{"class":3069},[3055,22150,3297],{"class":3168},[3055,22152,3172],{"class":3069},[3055,22154,5988],{"class":3302},[3055,22156,8094],{"class":8093},[3055,22158,22159],{"class":3302},"Total URLs crawled: ",[3055,22161,3307],{"class":3306},[3055,22163,22164],{"class":3126},"visitedUrls",[3055,22166,3080],{"class":3306},[3055,22168,3315],{"class":3126},[3055,22170,3318],{"class":3306},[3055,22172,3321],{"class":3302},[3055,22174,3324],{"class":3069},[3055,22176,22177,22179,22181,22183,22185,22187,22189,22191,22193,22195,22197],{"class":3057,"line":7762},[3055,22178,5957],{"class":3061},[3055,22180,3204],{"class":3069},[3055,22182,3123],{"class":3122},[3055,22184,20066],{"class":3126},[3055,22186,5967],{"class":3061},[3055,22188,22121],{"class":3126},[3055,22190,3080],{"class":3069},[3055,22192,8354],{"class":3168},[3055,22194,3172],{"class":3069},[3055,22196,3181],{"class":3175},[3055,22198,4915],{"class":3069},[3055,22200,22201],{"class":3057,"line":7782},[3055,22202,3195],{"class":3069},[3055,22204,22205,22207,22209,22211,22213,22215,22217,22219,22221,22223],{"class":3057,"line":7800},[3055,22206,3763],{"class":3126},[3055,22208,3080],{"class":3069},[3055,22210,3297],{"class":3168},[3055,22212,3172],{"class":3069},[3055,22214,11569],{"class":3302},[3055,22216,3307],{"class":3306},[3055,22218,20283],{"class":3126},[3055,22220,3318],{"class":3306},[3055,22222,3321],{"class":3302},[3055,22224,3324],{"class":3069},[3055,22226,22227],{"class":3057,"line":7805},[3055,22228,3484],{"class":3069},[2964,22230,22231,3490],{},[2977,22232,20450],{},[3009,22234,22235,22241,22251],{},[3012,22236,19911,22237,22240],{},[2968,22238,22239],{},"_visited.TryAdd(url, true)"," для перевірки чи URL вже відвіданий",[3012,22242,22243,22244,22246,22247,22250],{},"Якщо ",[2968,22245,4683],{}," повертає ",[2968,22248,22249],{},"false"," — URL вже обробляється іншим потоком",[3012,22252,22253],{},"Worker завершується коли черга порожня та всі інші workers теж idle",[3025,22255],{},[2959,22257,22259],{"id":22258},"підсумок","Підсумок",[2964,22261,22262],{},"У цій темі ви дізналися про:",[2964,22264,22265,3490],{},[2977,22266,19108],{},[3009,22268,22269,22274,22283],{},[3012,22270,22271,22273],{},[2968,22272,19125],{}," — striped locking для високої throughput",[3012,22275,22276,2971,22278,2971,22280,22282],{},[2968,22277,9070],{},[2968,22279,10028],{},[2968,22281,10467],{}," — lock-free колекції",[3012,22284,22285,22287],{},[2968,22286,11866],{}," — bounded producer-consumer з блокуючими операціями",[2964,22289,22290,3490],{},[2977,22291,13442],{},[3009,22293,22294,22297,22300,22303],{},[3012,22295,22296],{},"Thread-safe через immutability (не потрібні locks для читання)",[3012,22298,22299],{},"Structural sharing для ефективності",[3012,22301,22302],{},"Builder pattern для batch операцій",[3012,22304,22305],{},"Ідеально для read-heavy сценаріїв та snapshots",[2964,22307,22308,3490],{},[2977,22309,22310],{},"Ключові принципи",[3877,22312,22313,22319,22325,22330],{},[3012,22314,22315,22318],{},[2977,22316,22317],{},"Не використовуйте звичайні колекції у багатопотоковому коді"," — це призводить до corruption",[3012,22320,22321,22324],{},[2977,22322,22323],{},"Lock навколо колекції працює, але повільно"," — використовуйте спеціалізовані concurrent колекції",[3012,22326,22327],{},[2977,22328,22329],{},"Concurrent для частих модифікацій, Immutable для частих читань",[3012,22331,22332,13427],{},[2977,22333,22334],{},"BlockingCollection для синхронного producer-consumer, Channels для async",[2964,22336,22337,5292,22340,22345],{},[2977,22338,22339],{},"Наступна тема",[22341,22342,22344],"a",{"href":22343},"./tpl-parallel-plinq","TPL, Parallel та PLINQ"," — Task Parallel Library, data parallelism та PLINQ для паралельної обробки даних.",[3044,22347,22349],{"className":22348,"code":3051,"language":3496},[3494],[2968,22350,3051],{"__ignoreMap":3051},[22352,22353,22354],"style",{},"html pre.shiki code .sCDza, html code.shiki .sCDza{--shiki-light:#AF00DB;--shiki-default:#CE92A4;--shiki-dark:#CE92A4}html pre.shiki code .sN1BT, html code.shiki .sN1BT{--shiki-light:#267F99;--shiki-default:#4EC9B0;--shiki-dark:#4EC9B0}html pre.shiki code .sHH4Y, html code.shiki .sHH4Y{--shiki-light:#000000;--shiki-default:#D4D4D4;--shiki-dark:#D4D4D4}html pre.shiki code .su1O8, html code.shiki .su1O8{--shiki-light:#0000FF;--shiki-default:#569CD6;--shiki-dark:#569CD6}html pre.shiki code .siwwj, html code.shiki .siwwj{--shiki-light:#001080;--shiki-default:#9CDCFE;--shiki-dark:#9CDCFE}html pre.shiki code .spJ8K, html code.shiki .spJ8K{--shiki-light:#008000;--shiki-default:#6A9955;--shiki-dark:#6A9955}html pre.shiki code .s8Opu, html code.shiki .s8Opu{--shiki-light:#795E26;--shiki-default:#DCDCAA;--shiki-dark:#DCDCAA}html pre.shiki code .sJj4R, html code.shiki .sJj4R{--shiki-light:#098658;--shiki-default:#B5CEA8;--shiki-dark:#B5CEA8}html pre.shiki code .sbdoH, html code.shiki .sbdoH{--shiki-light:#A31515;--shiki-default:#CE9178;--shiki-dark:#CE9178}html pre.shiki code .sD7JJ, html code.shiki .sD7JJ{--shiki-light:#000000FF;--shiki-default:#D4D4D4;--shiki-dark:#D4D4D4}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sjcCO, html code.shiki .sjcCO{--shiki-light:#EE0000;--shiki-default:#D7BA7D;--shiki-dark:#D7BA7D}html pre.shiki code .se1LK, html code.shiki .se1LK{--shiki-light:#CD3131;--shiki-default:#F44747;--shiki-dark:#F44747}html pre.shiki code .s5IvJ, html code.shiki .s5IvJ{--shiki-light:#000000;--shiki-default:#C8C8C8;--shiki-dark:#C8C8C8}",{"title":3051,"searchDepth":3073,"depth":3073,"links":22356},[22357,22358,22365,22372,22378,22383,22391,22399,22416,22424,22427,22432],{"id":2961,"depth":3073,"text":2962},{"id":3029,"depth":3073,"text":3030,"children":22359},[22360,22362,22363,22364],{"id":3034,"depth":3093,"text":22361},"Демонстрація: List Corruption",{"id":3510,"depth":3093,"text":3511},{"id":3914,"depth":3093,"text":3915},{"id":4025,"depth":3093,"text":4026},{"id":4264,"depth":3073,"text":4265,"children":22366},[22367,22368,22369,22370,22371],{"id":4268,"depth":3093,"text":4269},{"id":4330,"depth":3093,"text":4331},{"id":4621,"depth":3093,"text":4622},{"id":6708,"depth":3093,"text":6709},{"id":7858,"depth":3093,"text":7859},{"id":9057,"depth":3073,"text":22373,"children":22374},"ConcurrentQueue — Lock-Free FIFO",[22375,22376,22377],{"id":9064,"depth":3093,"text":9065},{"id":9126,"depth":3093,"text":4622},{"id":9460,"depth":3093,"text":9461},{"id":10015,"depth":3073,"text":22379,"children":22380},"ConcurrentStack — Lock-Free LIFO",[22381,22382],{"id":10022,"depth":3093,"text":10023},{"id":10067,"depth":3093,"text":4622},{"id":10454,"depth":3073,"text":22384,"children":22385},"ConcurrentBag — Thread-Local Optimization",[22386,22387,22388,22389,22390],{"id":10461,"depth":3093,"text":10462},{"id":10509,"depth":3093,"text":10510},{"id":11098,"depth":3093,"text":11099},{"id":11151,"depth":3093,"text":11152},{"id":11588,"depth":3093,"text":11589},{"id":11854,"depth":3073,"text":22392,"children":22393},"BlockingCollection — Bounded Producer-Consumer",[22394,22395,22396,22397,22398],{"id":11860,"depth":3093,"text":11861},{"id":11909,"depth":3093,"text":4622},{"id":12293,"depth":3093,"text":12294},{"id":12748,"depth":3093,"text":12749},{"id":13374,"depth":3093,"text":13375},{"id":13441,"depth":3073,"text":13442,"children":22400},[22401,22402,22403,22404,22405,22406,22407,22409,22411,22413,22414,22415],{"id":13445,"depth":3093,"text":13446},{"id":13613,"depth":3093,"text":13614},{"id":13644,"depth":3093,"text":13645},{"id":14180,"depth":3093,"text":14181},{"id":14941,"depth":3093,"text":14942},{"id":15403,"depth":3093,"text":15404},{"id":16045,"depth":3093,"text":22408},"ImmutableStack та ImmutableQueue",{"id":16454,"depth":3093,"text":22410},"ImmutableHashSet та ImmutableSortedSet",{"id":17083,"depth":3093,"text":22412},"ImmutableArray — Спеціальний Випадок",{"id":17494,"depth":3093,"text":17495},{"id":18278,"depth":3093,"text":18279},{"id":18399,"depth":3093,"text":18400},{"id":18504,"depth":3073,"text":18505,"children":22417},[22418,22419,22420,22421,22422,22423],{"id":18511,"depth":3093,"text":18512},{"id":18916,"depth":3093,"text":18917},{"id":18939,"depth":3093,"text":18940},{"id":18964,"depth":3093,"text":18965},{"id":18986,"depth":3093,"text":18987},{"id":19006,"depth":3093,"text":19007},{"id":19072,"depth":3073,"text":19073,"children":22425},[22426],{"id":19421,"depth":3093,"text":19422},{"id":19890,"depth":3073,"text":19891,"children":22428},[22429,22430,22431],{"id":19894,"depth":3093,"text":19895},{"id":20464,"depth":3093,"text":20465},{"id":21142,"depth":3093,"text":21143},{"id":22258,"depth":3073,"text":22259},"Thread-safe колекції в .NET — ConcurrentDictionary з striped locking, lock-free ConcurrentQueue/Stack/Bag, BlockingCollection для producer-consumer, Immutable Collections та persistent data structures. Детальний розбір архітектури, benchmarks та практичні сценарії.","md",null,{},{"title":328,"description":22433},"RfJWE4XIQh900_fJo7tP0oaQleg9NVY3jOrZ5sawoKw",[22440,22442],{"title":324,"path":325,"stem":326,"description":22441,"children":-1},"Глибокий розбір внутрішньої архітектури ThreadPool — Work Stealing Algorithm, Hill Climbing детально, IOCP механізм, custom ThreadPool реалізація, production tuning та advanced patterns для оптимізації багатопотокових застосунків.",{"title":332,"path":333,"stem":334,"description":22443,"children":-1},"Глибокий академічний розбір Task Parallel Library — еволюція від Thread до Task, Task\u003CT>, композиція через WhenAll/WhenAny, CancellationToken, exception handling та AggregateException. Теорія і практика сучасного паралелізму.",1777912542640]