Какой рейтинг вас больше интересует?
|
Главная / Главные темы / Тэг «собседование»
Системные вещи. Ответы Часть 3. 2015-07-02 13:57:00
Что такое ...
+ развернуть текст сохранённая копия
Что такое виртуальная память?Виртуа́льная па́мять — технология управления памятью для многозадачных операционных систем. Позволяет увеличить эффективность использования памяти несколькими одновременно работающими программами, организовав множество независимых адресных пространств, и обеспечить защиту памяти между различными приложениями. Также позволяет программисту использовать больше памяти, чем установлено в компьютере, за счет откачки неиспользуемых страниц на вторичное хранилище. Применение механизма виртуальной памяти позволяет: - упростить адресацию памяти клиентским программным обеспечением;
- рационально управлять оперативной памятью компьютера (хранить в ней только активно используемые области памяти);
- изолировать процессы друг от друга (процесс полагает, что монопольно владеет всей памятью).
Как работает paging?Страничная память (paging) — способ организации виртуальной памяти, при котором единицей отображения виртуальных адресов на физические является страница. Типичный размер 4096 байт, для некоторых архитектур до 128 КБ. Поддержка такого режима присутствует в большинстве 32битных и 64битных процессоров. Решаемые задачи - поддержка изоляции процессов и защиты памяти путём создания своего собственного виртуального адресного пространства для каждого процесса
- поддержка изоляции области ядра от кода пользовательского режима
- поддержка памяти «только для чтения» и неисполняемой памяти
- поддержка отгрузки давно не используемых страниц в область подкачки на диске
- поддержка отображённых в память файлов, в том числе загрузочных модулей
- поддержка разделяемой между процессами памяти, в том числе с копированием-по-записи для экономии физических страниц
- поддержка системного вызова fork() в ОС семейства UNIX
Запись таблицы страниц обычно содержит в себе следующую информацию: - флаг «страница отображена»
- физический адрес
- флаг «страница доступна из режима пользователя». При неустановке данного флага страница доступна только из режима ядра.
- флаг «страница доступна только на чтение».
- флаг «страница недоступна на исполнение».
- режим использования кэша для страницы. Особенно часто используется для видеопамяти и для отображенных в память регистров устройств (полное отсутствие кэширования).
Так как число записей в одной таблице ограничено и зависит от размера записи и размера страницы, используется многоуровневая организация таблиц, часто 2 или 3 уровня, иногда 4 уровня (для 64-х разрядных архитектур). В случае 2 уровней используется «директория» страниц, имеющая в себе записи, указывающие на физические адреса таблиц страниц. Таблицы содержат в себе записи, указывающие уже на страницы данных. В случае 3 уровней возникает ещё и супер-директория, содержащая в себе записи, указывающие на несколько директорий. Старшие биты виртуального адреса указывают на номер записи в директории, средние — номер записи в таблице, младшие (адрес внутри страницы) попадают в физический адрес без трансляции. Формат записей таблиц, их размер, размер страницы и организация таблиц зависит от типа процессора, а иногда и от режима его работы. Исторически, x86 использует 32битные PTE, 32битные виртуальные адреса, 4KB страницы, 1024 записи в таблице, двухуровневые таблицы, старшие 10 бит виртуального адреса — номер записи в директории, следующие 10 — номер записи в таблице, младшие 12 — адрес внутри страницы. Физический адрес директории или же супер-директории загружен в один из управляющих регистров процессора.
Если обращение к памяти не может быть оттранслировано через TLB, то микрокод процессора обращается к таблицам страниц и пытается загрузить PTE оттуда в TLB. Если и после такой попытки сохранились проблемы, то процессор исполняет специальное прерывание, называемое «отказ страницы» (page fault). Обработчик этого прерывания находится в подсистеме виртуальной памяти ядра ОС. Причины отказа страницы (page fault): - не существует таблицы, отображающей данный регион
- PTE не имеет взведённого флага «страница отображена».
- попытка обратиться из пользовательского режима к странице «только для ядра».
- попытка записи в страницу «только для чтения».
- попытка исполнения кода из страницы «исполнение запрещено».
Обработчик отказов в ядре может загрузить нужную страницу из файла или же из области подкачки, может создать доступную на запись копию страницы «только для чтения», а может и возбудить исключительную ситуацию в данном процессе. Каждый процесс имеет свой собственный набор таблиц страниц. Регистр «директория страниц» перегружается при каждом переключении контекста процесса. Также необходимо сбросить ту часть TLB, которая относится к данному процессу. В большинстве случаев ядро ОС помещается в то же адресное пространство, что и процессы, для него резервируются верхние 1-2 гигабайта 32битного адресного пространства каждого процесса. Это делается с целью избежать переключения таблиц страниц при входе в ядро и выходе из него. Страницы ядра помечаются как недоступные для кода режима пользователя.
Так как память ядра одинакова у всех процессов, соответствующие ей TLB не нужно перегружать после переключения процесса. Для этой оптимизации x86 поддерживает флаг «глобальный» у PTE. PAE, x64, IOMMU?В архитектуре x86_64 возможно использовать страницы размером 4 килобайта (4096 байт), 2 мегабайта, и (в некоторых AMD64) 1 гигабайт. Организация страниц для этой архитектуры имеет 4 уровня. Physical Address Extension (PAE) — режим работы встроенного блока управления памятью x86-совместимых процессоров, в котором используются 64-битные элементы таблиц страниц (из которых для адресации используются только 36 бит), c помощью которых процессор может адресовать 64 ГБ физической памяти (вместо 4 ГБ, адресуемых при использовании 32-разрядных таблиц), хотя каждая задача (программа) всё равно может адресовать максимум до 4 ГБ виртуальной памяти. Также, в новых моделях процессоров в PAE-режиме старший бит элемента таблицы страниц отвечает за запрет исполнения кода в странице, что затрудняет атаку по методу переполнения буфера.
IOMMU — блок управления памятью (MMU) для операций ввода-вывода. Так же как традиционный, процессорный блок управления памятью, который переводит виртуальные адреса, видимые процессором в физические, этот блок занимается трансляцией виртуальных адресов, видимых аппаратным устройством, в физические адреса. Некоторые IOMMU также позволяют задавать различные ограничения операций ввода-вывода для защиты от неправильно работающих устройств или для изоляции, например, при использовании виртуализации.
При наличии IOMMU у аппаратуры имеется возможность проводить DMA-операции не только по физическим адресам, но и по логическим (виртуальным). Такая возможность упрощает устройства, которым больше не нужно заботиться о поддержке DMA по разрывному (с точки зрения физических адресов) региону памяти. Недостатками использования IOMMU по сравнению с прямой физической адресацией памяти в DMA запросах являются: - Некоторое ухудшение производительности из-за необходимости транслирования адресов и расходов на управление, например, проход по иерархии таблицы страниц.
- Дополнительное потребление памяти для хранения таблиц отображения. Может быть уменьшен при использовании основных таблиц трансляции адресов процессора.
IOMMU используется для прямой работы виртуализованных операционных систем с оборудованием основной системы. Наличие IOMMU для таких комбинаций позволяет повысить безопасность, производительность и упростить реализацию виртуальной машины. Что такое прерывание? Какие они бывают?Прерывание — сигнал, сообщающий процессору о наступлении какого-либо события. При этом выполнение текущей последовательности команд приостанавливается, и управление передаётся обработчику прерывания. В зависимости от источника возникновения сигнала, прерывания делятся на: - аппаратные — события, которые исходят от внешних источников и могут произойти в любой произвольный момент. Факт возникновения в системе такого прерывания трактуется как запрос на прерывание (IRQ);
- внутренние — события в самом процессоре как результат нарушения каких-то условий при исполнении машинного кода: деление на ноль или переполнение стека, обращение к недопустимым адресам памяти или недопустимый код операции;
- программные (частный случай внутреннего прерывания) — инициируются исполнением специальной инструкции в коде программы. Программные прерывания, как правило, используются для обращения к функциям встроенного программного обеспечения (firmware), драйверов и операционной системы.
Аппаратные прерывания в зависимости от возможности запрета делятся на: - маскируемые — прерывания, которые можно запрещать установкой соответствующих битов в регистре маскирования прерываний;
- немаскируемые (Non-maskable interrupt, NMI) — обрабатываются всегда, независимо от запретов на другие прерывания. К примеру, такое прерывание может быть вызвано сбоем в микросхеме памяти.
Как происходит их обработка? Что со стеками?Обработчики прерываний обычно пишутся таким образом, чтобы время их обработки было как можно меньшим, поскольку во время их работы могут не обрабатываться другие прерывания, а если их будет много (особенно от одного источника), то они могут теряться.
До окончания обработки прерывания обычно устанавливается запрет на обработку этого типа прерывания, чтобы процессор не входил в цикл обработки одного прерывания. Все источники прерываний делятся на классы и каждому классу назначается свой уровень приоритета запроса на прерывание. Приоритеты могут обслуживаться как относительные и абсолютные. - Относительное обслуживание прерываний означает, что если во время обработки прерывания поступает более приоритетное прерывание, то это прерывание будет обработано только после завершения текущей процедуры обработки прерывания.
- Абсолютное обслуживание прерываний означает, что если во время обработки прерывания поступает более приоритетное прерывание, то текущая процедура обработки прерывания вытесняется, и процессор начинает выполнять обработку вновь поступившего более приоритетного прерывания. После завершения этой процедуры процессор возвращается к выполнению вытесненной процедуры обработки прерывания.
На этом на сегодня всё, читайте продолжение в следующем посте.
Тэги: система, собседование
Системные вещи. Ответы Часть 2. 2015-07-01 17:54:00
Введение
+ развернуть текст сохранённая копия
ВведениеПродолжаю публиковать ответы на вопросы на наших собеседованиях. Вопрос про режимы ядра и многие последующие вопросы привязаны к той ОС, в которой вы работаете. В нашей компании активно разрабатываются проекты в Windows и Linux. Однако, так как большинство кандидатов лучше знают Windows, то и ответы будут публиковаться для Windows, если это не оговорено дополнительно. Кстати, по всем системным вещам Windows стоит обращаться к замечательной книге М. Руссинович, Д. Соломон - Внутреннее устройство Microsoft Windows. В ней даны подробные ответы на все системные вопросы нашего собеседования. Если же вам больше интересно как все работает внутри Linux, то я рекомендую обратиться к книге Таненбаум Э. - Современные операционные системы. Что такое режим ядра и режим пользователя?Для предотвращения доступа приложений к критически важным данным операционной системы и устранения риска их модификации Windows использует два режима доступа к процессору: пользовательский (user mode) и ядра (kernel mode). Код приложений работает в пользовательском режиме, тогда как код операционной системы (например, системные сервисы и драйверы устройств) — в режиме ядра. B режиме ядра предоставляется доступ ко всей системной памяти и разрешается выполнять любые машинные команды процессора. Предоставляя операционной системе более высокий уровень привилегий, чем прикладным программам, процессор позволяет разработчикам операционных систем реализовать такие архитектуры, которые не дают возможности сбойным приложениям нарушать стабильность работы всей системы. Windows не предусматривает никакой защиты системной памяти от компонентов, работающих в режиме ядра. Иначе говоря, код операционной системы и драйверов устройств в режиме ядра получает полный доступ к системной памяти и может обходить средства защиты Windows для обращения к любым объектам. Поскольку основная часть кода Windows выполняется в режиме ядра, крайне важно, чтобы компоненты, работающие в этом режиме, были тщательно продуманы и протестированы. CPL, RPL, DPL?Существует четыре уровня привилегий (PL) сегментов (0-3). Привилегированность увеличивается с уменьшением номера. На нулевом уровне позволяется использование привилегированных инструкций. Уровень привилегий сегмента (Descriptor Privilege Level) соответствует значению поля DPL в дескрипторе сегмента. Текущий уровень привилегий (Current Privilege Level) соответствует уровню привилегий сегмента кода, селектор которого загружен в регистр CS (то есть уровню привилегий выполняющегося сегмента кода). Запрашиваемый уровень привилегий (Requested Privilege Level) находится в двух младших битах селектора (задаётся программой). Как происходит взаимодействие между режимом пользователя и ядра? SYSENTER, int2e?- Вызов функции, например, CreateFile разворачивается в вызов функции из NtDll.dll — «прослойке» между режимом пользователя и режимом ядра. В ней находится нужная нам функция ядра. Эта функция помещает в регистр EAX свой уникальный номер. Этот номер специфичен для каждой версии ОС и может измениться при установке Service Pack или другого обновления системы, которое затрагивает ядро.
- Далее, в EDX помещается адрес вершины стека параметров, в большинстве случаев это значение регистра ESP. Дело в том, что в режиме ядра и режиме пользователя используется разный стек, и при переходе в ядро стек будет переключен.
- На старых процессорах и ОС переключение выполняется с помощью прерывания 0x2e, на современных же для этого существует специальная инструкция процессора: SysEnter для Intel, SysCall для AMD. Int2e поддерживается в режиме совместимости современными процессорами.
- Процессор переключает EIP(RIP), на специальное значение, которое хранится в регистре MSR_SYSENTER_EIP. Этот регистр заполняется системой при загрузке.
- В результате происходит переход в специальную функцию - KiFastCallEntry().
- После завершения выполнении функции, происходит возврат из режима ядра с помощью iret или Sy
- Ядро, используя значение в регистре EAX, находит запись в таблице KiServiceDescriptorTable и осуществляет вызов нужной функции ядра.
- sysExit/SysRet
На этом на сегодня всё, продолжение читайте в следующем посте.
Тэги: система, собседование
Системные вещи. Ответы Часть 1. 2015-06-29 15:17:00
Введение
+ развернуть текст сохранённая копия
ВведениеКак и обещал, начинаю потихоньку публиковать ответы. Всем понятно, что многие вопросы очень обширны и обсуждать их подробно с каждым кандидатом нет смысла. Стоит отметить, что у нас никто не ждет от кандидатов заученные наизусть статьи и мануалы. Мы лишь хотим узнать, понимает ли человек вопрос и может ли пояснить, что это такое.
Я запишу лишь некоторый минимум, который мы хотели бы услышать от кандидата по каждому вопросу. Что такое архитектура процессора?Архитектура процессора — количественная составляющая компонентов процессора компьютера (например, регистры процессора). С точки зрения программиста — совместимость с определённым набором команд (например, процессоры, совместимые с командами Intel х86), структуры команд и способ исполнения. С точки зрения аппаратной составляющей вычислительной системы — это некий набор свойств и качеств, присущий целому семейству процессоров (например, RISC и CISC).
Здесь кандидат может получить жирный плюс в карму, если сможет рассказать про Arm и какие-то ее особенности. Не могу сказать, что мы активно используем эту архитектуру, но все же это будет отмечено на собеседовании. Ведь если кандидат смог разобраться в этой архитектуре самостоятельно, скорее всего сможет разобраться и в других сложных вопросах. Рассказ про особенности CISC и RISC так же будет большим плюсом. Чем x86 отличается от x64?Большинство кандидатов при ответе на этот вопрос начинают рассказывать о том, что в x86 компьютере нельзя использовать больше 3.5 Гб оперативной памяти. В этом случае мы сразу упоминаем про PAE и просим освятить этот вопрос поподробнее. К сожалению, пока ни один кандидат не смог ничего нам рассказать. На самом деле компьютеры вполне успешно использовали больше 3.5 Гб оперативной памяти и без новой архитектуры, а различий куда больше: - Размер регистров процессора. Очевидно, что в x64 размер регистров общего назначения, арифметических и логических операций над целыми числами и виртуальных адресов стал равен 64-битам.
- Количество регистров процессора.
- Новый режим работы Long mode.
Есть так же несколько отличий для программиста: - Размер виртуального адресного пространства увеличился с 3.5 Гб до 20Гб.
- В C\C++ появились новые типы и изменился размер некоторых старых типов.
- Использование fastcall в качестве calling convention (смотри MSDN).
Для тех, кто решит капнуть этот вопрос максимально глубоко следует обратиться к мануалам от Intel. Что такое защищенный и реальный режимы работы?Вопрос про режимы работы процессора напрямую связан с вопросом, что такое адресс в памяти и на мой взгляд является одним из самых важных вопросов, с которыми сталкивается программист в C\C++. Ошибки работы с памяти или интерпретации тех или иных адессов являются одними из самых частых на моей практике. К моему большому сожалению, многие современные программисты не понимают как работает память в современном компьютере. В реальном режиме при вычислении линейного адреса, по которому процессор собирается читать содержимое памяти или писать в неё, сегментная часть адреса умножается на 16 и суммируется со смещением. Таким образом, адреса 0400h:0001h и 0000h:4001h ссылаются на один и тот же физический адрес, так как 400h×16+1 = 0×16+4001h. Такой способ вычисления физического адреса позволяет адресовать 1 Мб + 64 Кб − 16 байт памяти (диапазон адресов 0000h…10FFEFh).
Защищённый режим — режим работы x86-совместимых процессоров. Суть защищённого режима в следующем: программист и разрабатываемые им программы используют логическое адресное пространство. Логический адрес преобразуется в физический адрес автоматически с помощью схемы управления памятью (MMU). При этом содержимое сегментного регистра не связано напрямую с физическим адресом, а является номером сегмента в соответствующей таблице. Благодаря защищённому режиму, в памяти может храниться только та часть программы, которая необходима в данный момент, а остальная часть может храниться во внешней памяти (например, на жёстком диске). Физический адрес формируется следующим образом. В сегментных регистрах хранится селектор, содержащий индекс дескриптора в таблице дескрипторов (13 бит), 1 бит, определяющий к какой таблице дескрипторов будет производиться обращение и 2 бита запрашиваемого уровня привилегий. Далее происходит обращение к соответствующей таблице дескрипторов и соответствующему дескриптору, который содержит начальный 24-битный адрес сегмента, размер сегмента и права доступа, после чего вычисляется необходимый физический адрес путём сложения адреса сегмента со смещением из 16-разрядного регистра. Вопрос про режимы работы процессора тесно связан со страничной организацией памяти и будет кратко рассмотрен в других постах. За дополнительной информацией можно обращаться в wiki или к различной литературе. Сегменты, IDT, GDT, LDT, TSS(TR)?Вопрос про сегменты и их назначение задается только тем кандидатам, которые отлично понимают, что такое архитектура и режимы работы процессора.
Таблица векторов прерываний (IDT) используется в архитектуре x86 и служит для определения корректного ответа на прерывания и исключения. Начиная с процессора 80286, адрес в физической памяти и размер таблицы прерываний определяется 48-битным регистром IDTR. В IDT используются следующие типы прерываний: аппаратные прерывания, программные прерывания и прерывания, зарезервированные процессором, называемые исключениями (первые 32) на случай возникновения некоторых событий. В реальном режиме элементом IDT является 32-битный FAR-адрес обработчика прерывания. В защищённом режиме элементом IDT является шлюз прерывания длиной 8 байт, содержащий сегментный (логический) адрес обработчика прерывания, права доступа и др. GDT (глобальная таблица дескрипторов) — служебная структура данных в архитектуре x86, определяющая глобальные сегменты. Её расположение в физической памяти и размер определяются системным регистром GDTR. Дескрипторы LDT и сегментов задач (TSS) могут находиться только здесь. Особенностью GDT является то, что у неё запрещён доступ к нулевому дескриптору. Обращение к нему вызывает исключение #GP, что предотвращает обращение к памяти с использованием незагруженного сегментного регистра. LDT (локальная таблица дескрипторов). В отличие от GDT, LDT может быть много (соответственно количеству потоков, но не обязательно). Каждая задача может иметь свою. На расположение таблицы текущей задачи указывает регистр LDTR. Размер и расположение LDT в линейной памяти определяются дескриптором LDT из GDT (но это не означает, что размер LDT может быть больше 65536 байт). TSS (сегмент состояния задачи) — специальная структура в архитектуре x86, содержащая информацию о процессе. Может использоваться ОС для диспетчеризации задач, но обычно применяется только для переключения на стек ядра при обработке прерываний и исключений. В TSS содержится информация о: - Состоянии регистров процессора;
- Разрешениях на использование портов ввода-вывода;
- Указатели на стек внутреннего уровня;
- Ссылка на предыдущую запись TSS (для задач диспетчеризации)
На этом на сегодня всё. Остальные ответы читайте в следующем посте.
Тэги: система, собседование
Наши собеседования и наши вопросы 2015-06-29 13:35:00
Введение
+ развернуть текст сохранённая копия
ВведениеЗа последний год работы в компании мне довелось провести более 50 собеседований. Большинство из них проводилось на позицию программист-стажер\программист C\C++.
Стоит отметить, что мне очень нравится беседовать с новыми людьми, особенно с программистами. Ведь очень интересно, чем люди занимаются в нашей отрасли и какие проекты делают в других компаниях. Когда мне первый раз предложили провести собеседование нового кандидата, у компании не было какого-то четкого порядка проведения собеседования, не было списка вопросов или тестовых заданий. Коллеги, которые проводили собеседования, имели некоторый стандартный список вопросов в своей голове, которые и предлагались кандидатам. Когда я сам устраивался в компанию, я отвечал именно на эти вопросы. Мне такой слегка хаотичный порядок сразу не понравился. Порой собеседования проводят разные люди, при этом вопросы у каждого в голове свои и отличаются от вопросов коллег. Это может привести к тому, что одна из областей не будет затронута вообще и вы возьмете неподходящего кандидата. Дабы избежать таких проблем, мы составили 2 списка вопросов (для стажеров и опытных программистов), а затем и небольшой тест, который проходят кандидаты перед собеседованием. Данный тест позволяет оценить базовые знания кандидата и не тратить время на дальнейшее собеседование в случае, если такие знания отсутствуют. Также мы используем лист с тестом для записи комментариев и оценок по каждой области после собеседования. Он отлично помогает вспомнить каждого конкретного кандидата после многих собеседований. Наш тест вряд ли будет кому-то интересен, поэтому и публиковать его я не буду. А вот наши вопросы и, соответственно, ответы на них приведу в конце данного поста. Возможно эти вопросы помогут кому-то в подготовке к собеседованию (почему-то в интернете не так много вопросов для подготовки к собеседованию на должность программиста С\С++). Всем хочется проводить собеседование "активного", подготовленного кандидата. Я, например, очень надеюсь, что кто-то из наших кандидатов придет подготовленным. К сожалению, на данный момент мой опыт собеседований весьма негативный. Большинство кандидатов, которые приходят к нам в компанию, обладают крайне низким уровнем знаний. Конечно, студент, приходящий на собеседование, редко когда обладает большим багажом знаний и навыков. Но когда технический специалист после 3-4 курса института не знает, что такое DNS, как применяется ключевое слово static, то это п....ечально. Еще печальнее, что такие знания порой отсутствуют у людей имеющих 1-2-3 года работы на схожих позициях :(. Очень хотелось бы знать, почему такие ситуации имеют место быть. Пока, к сожалению, я не могу назвать причину происходящего. Возможно, дело в том, что компания предлагает среднюю зарплату в городе. Или в том, что все серьёзные программисты едут работать из Зеленограда в Москву. P.S. Замечу, что помимо вопросов к собеседованию я планирую постепенно публиковать ответы, которые мы ожидаем от кандидатов. Как вы видите, список вопросов достаточно обширный и захватывает многие около-компьютерные вопросы. Стоит отметить, что мы не мучаем кандидата всеми этими вопросами. Но если мы понимаем, что в данной области человек обладает какими-то знаниями, то мы стараемся копнуть как можно глубже, чтобы выяснить границу его знаний. Вопросы и ответыИтак, первая часть вопросов - Системные вещи: - Что такое архитектура процессора? Чем x86 отличается от x64?
- Что такое защищенный и реальный режимы работы? Сегменты, IDT, GDT, LDT, TSS(TR)?
- Что такое режим ядра и режим пользователя? CPL, RPL, DPL?
- Как происходит взаимодействие между режимом пользователя и ядра? SYSENTER, int2e?
- Что такое виртуальная память? Как работает paging? PAE, x64, IOMMU?
- Что такое прерывание? Какие они бывают? Как происходит их обработка? Что со стеками?
- Подробно как происходит загрузка компьютера? А с UEFI?
- Что такое ядро ОС? Какие функции оно выполняет? Почему DOS не является ОС?
- Что такое драйвер? Чем он отличается от обычной программы?
- Что такое поток? Что он включает? Как и кем создается? В каких состояниях может быть?
- Что такое HAL? Зачем он нужен?
- Форматы исполняемых файлов(ELF, COFF(PE)). Секции, таблица релокаций, PIC?
- Что такое реестр? Как он устроен? Где храниться?
- Что такое сервис (служба)? Чем он отличается от обычной программы?
- Что такое Unicode, какое отношение к нему имеют UTF16, UCS2LE, UTF8 и т.д.?
Тэги: c\c++, вопросы, общие, программист, с++, собседование
Главная / Главные темы / Тэг «собседование»
|
Взлеты Топ 5
Падения Топ 5
|