Какво е ОС? Избройте 2 ключови неща, които тя трябва да прави.
ОС е парче софтуер, което менажира хардуера и управлява потребителски процеси.
Какво е kernel, drivers, userland?
Ядрото е това, което има достъп до (почти) всичкия хардуер, всичко в ОС-а и което се грижи за потребителските процеси.
Драйвърите са код, който е чужд за ОС-а, който управлява конкретен вид хардуер.
Юзърленд-а са потребителски програми, без които една ОС би била безполезна.
Какво са Kernel space и User space и защо съществуват?
Първото е "привилегированата" част на една ОС.
Второто е там, където вървят потребителските процеси.
Това се прави за сигурнст - процесите да не се достъпват помежду си, както и да не омажат ядрото.
Какво е процес?
Абстракция за виртуална памет. Това е една потребителска програма, която има собствена памет.
Как (едно време) се е минавала границата User space / Kernel space?
Интеръпти.
Какви сегменти има в паметта на един процес?
Image files (code)
Stacks
Heaps
Static data
etc
Каква е разликата между статично и динамично линкване?
При статичното кодът на външните библиотеки се вкарва директно в изпълнимия файл. Той нараства по размер, но нямаме нужда от допълнителни файлове.
При динамичното кодът на външните библиотеки е в отделни файлове. В изпълнимия файл има само таблица с имена на зависимости.
Компютрите "говорят" на машинен език
Ние програмираме на човешко-четим език
Трябва някой по някакъв начин трябва да го обърне до машинен, за да може да бъде изпълнен от компютъра
Има (грубо-казано) 2 начина за това
При първия, една програма "превежда" човешкия език на машинен преди изпълнението му
Тя се нарича компилатор
Включва процеса на linking, за който говорихме предния път
При втория, една програма директно изпълнява човешкия език
Тя се нарича интерпретатор
Работи на принципа read-eval-print (REPL)
Компилацията отнема време (C++, anyone?)
Компилираният код се изпълнява по-бързо
Времето за зареждане на интерпретиран код може да е голямо
Интерпретируемите езици нямат нужда от build системи
По-често (и лесно) се ползват за rapid prototyping
Компилираният код остава същия през времето
Това може да е проблем, когато хардуерът става по-добър
Идеята е да компилираме човешкия език до междинен код (Java bytecode, MSIL)
Който после, по време на изпълнение, се компилира до машинен
Това, което прави вторичната компилация, се нарича runtime
Типичните примери за това са .NET/Java
По-бавен startup time, тъй като се налага междинния код да се транслира
Евентуално по-бързо изпълнение от чист native код по две причини:
При дълго вървящи процеси, runtime-ът може да оптимизира hot paths
Когато upgrade-нем хардуера и runtime-а, всички "стари" програми ще вървят по-бързо
Доста повече метаинформация, идваща от runtime-a
Благинки като garbage-collection, reflection
Междинният код се изпълнява от нещо наречено виртуална машина (JVM/CLR)
Обикновено използват JIT
Някои могат да интерпретират междинния код
Някои могат да правят и двете (JVM)
Къде се намира Python в картинката
Има bytecode
Няма JIT; винаги се интерпретира
Кешира се в .pyc файлове
В известен смисъл е виртуална машина
Имплементиран е на C
Части от стандартната библиотека са DLL-ове написани на C
Практически няма разлика между DLL и EXE
Съдържа изпълним код, import таблица, export таблица
Последната съдържа само имената на функциите за C DLL-и
За C++ такива съдържа в името си и имената на типовете на аргументите си
Не съдържат, обаче, дефиниции на типове
Как тогава можем да компилираме код, който използва функции от такива DLL-и?
С header файлове. Те съдържат дефинициите на типове, декларации на функции и т.н.
Java използва JAR файлове, а в .NET DLL-ите не са (просто) native такива
В тях има много метаинформация за всички типове, функции, etc
Те обикновено не се компилират, а интерпретират, което означава, че ship-ват код
Тогава нямаме проблем с липса на типова информация
Всяка програма работи с променливи, които се намират някъде в оперативната памет
Има няколко подхода за това къде може да се намират
В read-only паметта, например хардкоднати стойности в кода ни
На стека, ако това са локални променливи във функции, например
В heap-a, ако са променливи, които ще ни трябват по-продължително
За последните някой трябва да се грижи ръчно кога да бъдат освободени
Езици като C/C++
Това е най-бързото решение като скорост на изпълнение
Освобождаваме ресурси максимално бързо, когато не ни трябват
Стават МНОГО грешки
Причината за 90% от crash-овете на приложения
По-модерни езици като Java/.NET/Ruby/Go
По-бавно по време на изпълнение
По-късно освобождаване на ресурси
Но пък е programmer-proof