9Как `std::vector` управлява капацитета, нарастването, преразпределянето на паметта и стабилността на итераторите?
`std::vector` съхранява елементите в последователна памет и проследява както размера (`size`), така и капацитета (`capacity`). Размерът е броят на конструираните елементи, а капацитетът е количеството заделена памет, достъпно преди да се наложи ново заделяне. Когато добавянето на елементи надхвърли капацитета, векторът заделя по-голям блок памет, обикновено използвайки специфична за имплементацията стратегия за геометрично нарастване, премества или копира съществуващите елементи, унищожава старите и освобождава старата памет. Методът `reserve(n)` увеличава капацитета, без да променя размера, докато `resize(n)` променя размера чрез конструиране или унищожаване на елементи. Преразпределянето на паметта инвалидира всички итератори, референции и указатели към елементите. Дори и без преразпределяне, операции като `insert` и `erase` могат да инвалидират позициите в или след точката на модификация.
Опитайте да отговорите на този въпрос с треньор с ИИ
10Какви правила за инвалидиране трябва да знаете за непрекъснатите и базираните на възли стандартни контейнери?
Правилата за инвалидиране зависят от контейнера и операцията. Непрекъснатите контейнери като vector и string имат крехка стабилност на итераторите и референциите: нарастването им може да доведе до презаделяне на памет и да инвалидира всички итератори, референции и указатели, а операциите за вмъкване и изтриване могат да изместят елементи и да инвалидират позициите на или след промяната, дори и без презаделяне. Базираните на възли подредени контейнери като list, map, set и техните multi варианти обикновено запазват итераторите и референциите към съществуващите неизтрити елементи стабилни при вмъкване; изтриването на елемент инвалидира само итератора или референцията към този изтрит елемент. Неподредените контейнери също съхраняват елементите във възли, така че референциите и указателите към елементите обикновено са стабилни при прехеширане, но прехеширането инвалидира итераторите. Контейнерът deque има специални правила за сегментирано съхранение. На практика, проверявайте конкретния контейнер и операция, преди да съхранявате итератори или референции между модификациите.
Опитайте да отговорите на този въпрос с треньор с ИИ
11Сравнете `std::map`, `std::unordered_map` и контейнерите от тип flat-map за справочни таблици в бекенда.
`std::map` е подреден, обикновено базиран на дърво асоциативен контейнер с логаритмично време за търсене, вмъкване и изтриване; той е полезен, когато са важни сортираното обхождане, заявките в диапазон или гаранциите за подредба. `std::unordered_map` е базиран на хеш таблица със средно константно време за операции с точен ключ и без подредба на ключовете; често е добър избор по подразбиране за големи изменяеми справочни таблици, когато хеширането е ефективно. Контейнерът от тип flat-map съхранява сортирани двойки ключ/стойност последователно в паметта, което осигурява добра локалност на кеша и бързо обхождане и двоично търсене, но вмъкването и изтриването в средата отнемат линейно време. За справочни таблици в бекенда, избирайте въз основа на това дали работното натоварване изисква подредба или диапазони, предимно точни търсения, чести промени, предвидима латентност, режийни разходи на памет и поведение на кеша.
Опитайте да отговорите на този въпрос с треньор с ИИ
12Обяснете `std::optional` и типичните случаи на употреба в бекенда за представяне на липсващи стойности.
`std::optional<T>` представлява или съдържаща се стойност от тип `T`, или липса на стойност. Празната стойност се представя чрез `std::nullopt`; кодът може да провери с `has_value()` или да използва `optional` обекта в булев контекст, да достъпи стойността чрез `*` или `value()`, и да предостави стойност по подразбиране чрез `value_or()`. В бекенд кода това е полезно за полета в базата данни, допускащи `null`, незадължителни полета в заявки или конфигурации, липси в кеша или хранилището, където отсъствието на стойност е очаквано, както и за състояния на домейна, при които сигнална стойност като `-1` или празен низ би била двусмислена. Той моделира липсата на стойност, а не полиморфизъм или богата информация за грешки.
Опитайте да отговорите на този въпрос с треньор с ИИ
13Какво представляват `std::string_view` и `std::span` и какви рискове за времето на живот на обектите въвеждат непритежаващите изгледи?
`std::string_view` е непритежаващ изглед към непрекъсната последователност от символи; `std::span<T>` е непритежаващ изглед към непрекъсната последователност от `T`. Те са полезни за параметри без копиране (zero-copy) и буферни API интерфейси, тъй като съдържат указател и дължина, без да заделят или притежават памет. Основният риск е времето на живот: реферираната памет трябва да надживее изгледа и не трябва да бъде инвалидирана, докато той се използва. Връщането или съхраняването на изглед към временен, локален или унищожен обект, или към преалокиран контейнер, може да доведе до висящ изглед (dangling view).
Опитайте да отговорите на този въпрос с треньор с ИИ